{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Channel Estimation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/h5py/__init__.py:34: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.\n",
      "  from ._conv import register_converters as _register_converters\n",
      "Using TensorFlow backend.\n"
     ]
    }
   ],
   "source": [
    "import numpy as np \n",
    "from keras.models import Sequential\n",
    "from keras.layers import Dense\n",
    "from keras.layers import LSTM\n",
    "import scipy.signal as sig\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "from sklearn.model_selection import train_test_split\n",
    "from keras.layers import Input\n",
    "from keras.layers import concatenate\n",
    "from keras.models import Model\n",
    "from keras.utils import plot_model\n",
    "from IPython.display import SVG\n",
    "from keras.utils.vis_utils import model_to_dot\n",
    "from keras.layers import TimeDistributed\n",
    "from keras.layers import Bidirectional\n",
    "from keras.layers import RepeatVector\n",
    "from sklearn.metrics import mean_absolute_error, mean_squared_error\n",
    "import commpy as cp"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [],
   "source": [
    "def generate_channel_estimation_dataset(dataset_size, preamble_length, constellations, SNR):\n",
    "    QAMModem = cp.modulation.QAMModem(constellations)\n",
    "    \n",
    "    # use the constellation object to modulate the data bits into complex numbers\n",
    "    \n",
    "    preamble_bits = []\n",
    "    preamble_bits_convolved = [] \n",
    "    preambles_constellations = []\n",
    "    input_data_constellations = []\n",
    "    convolved_preambles = []\n",
    "    convolved_data_constellations = []\n",
    "    channels = []\n",
    "    least_squares_preambles = []\n",
    "    least_squares_preambles_convolved = []\n",
    "    \n",
    "    for i in range(dataset_size):\n",
    "       \n",
    "        preambles = np.random.randint(0, 2, preamble_length)\n",
    "        preamble_bits.append(preambles)\n",
    "        \n",
    "        \n",
    "        preambles_constellation =  QAMModem.modulate(preambles)\n",
    "        least_squares_preambles.append(preambles_constellation)\n",
    "\n",
    "        \n",
    "        real_preambles = np.real(preambles_constellation)\n",
    "        im_preambles = np.imag(preambles_constellation)\n",
    "        real_im_preambles = np.vstack((real_preambles,im_preambles)).reshape((-1,),order='F')\n",
    "        preambles_constellations.append(real_im_preambles)\n",
    "        channel_taps = [0, 0]\n",
    "        channel_taps[0] = np.random.uniform(-1, 1)\n",
    "        channel_taps[1] = np.random.uniform(-1, 1)\n",
    "        channel_taps = channel_taps / np.linalg.norm(channel_taps)\n",
    "        channels.append(channel_taps)\n",
    "        preamble_bits_convolved.append(sig.convolve(preambles, channel_taps, mode='same'))\n",
    "        \n",
    "        \n",
    "        preamble_conv = add_awgn_noise(sig.convolve(preambles_constellation, channel_taps, mode='same'), SNR)\n",
    "        least_squares_preambles_convolved.append(preamble_conv)\n",
    "        \n",
    "        real_preambles_conv = np.real(preamble_conv)\n",
    "        im_preambles_conv = np.imag(preamble_conv)\n",
    "        real_im_preambles_conv = np.vstack((real_preambles_conv,im_preambles_conv)).reshape((-1,),order='F')\n",
    "        convolved_preambles.append(real_im_preambles_conv)\n",
    "        \n",
    "        \n",
    "    X1 = np.hstack([preambles_constellations, np.array(convolved_preambles)])\n",
    "    channels = np.array(channels)\n",
    "#     plt.scatter(np.zeros(input_data_constellations.shape[1]), input_data_constellations[0])\n",
    "#     plt.show()\n",
    "    return X1, channels, np.array(least_squares_preambles, dtype='complex'), np.array(least_squares_preambles_convolved, dtype='complex')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {},
   "outputs": [],
   "source": [
    "def create_model(input_layer_dim, hidden_layer_dim, input_dim, output_dim):\n",
    "    model = Sequential()\n",
    "    model.add(Dense(input_layer_dim, input_dim=input_dim, activation='sigmoid'))\n",
    "    model.add(Dense(hidden_layer_dim, activation='sigmoid'))\n",
    "    model.add(Dense(output_dim, activation='tanh'))\n",
    "    model.compile(loss='mean_squared_error', optimizer='adam', metrics=['mae'])\n",
    "    return model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 105,
   "metadata": {},
   "outputs": [],
   "source": [
    "dataset_size = 50000\n",
    "preamble_length = 100\n",
    "QAM_scheme = 4\n",
    "preamble_data, channels, lstsq_preambles, lstsq_preamble_convolved = generate_channel_estimation_dataset(dataset_size, preamble_length, QAM_scheme)\n",
    "train_size = int(preamble_data.shape[0] * 0.8)\n",
    "preamble_train, preamble_test = preamble_data[:train_size], preamble_data[train_size:]\n",
    "channel_train, channel_test = channels[:train_size], channels[train_size:]\n",
    "lstsq_preambles_test, lstsq_preambles_convolved_test = lstsq_preambles[train_size:], lstsq_preamble_convolved[train_size:]\n",
    "# print(preamble_train.shape, preamble_test.shape)\n",
    "# print(channel_train.shape, channel_test.shape)\n",
    "# print(preamble_test, channel_test)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 103,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<svg height=\"296pt\" viewBox=\"0.00 0.00 328.56 296.00\" width=\"329pt\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g class=\"graph\" id=\"graph0\" transform=\"scale(1 1) rotate(0) translate(4 292)\">\n",
       "<title>G</title>\n",
       "<polygon fill=\"#ffffff\" points=\"-4,4 -4,-292 324.5557,-292 324.5557,4 -4,4\" stroke=\"transparent\"/>\n",
       "<!-- 5465377648 -->\n",
       "<g class=\"node\" id=\"node1\">\n",
       "<title>5465377648</title>\n",
       "<polygon fill=\"none\" points=\"0,-243.5 0,-287.5 320.5557,-287.5 320.5557,-243.5 0,-243.5\" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"90.6191\" y=\"-261.3\">dense_220_input: InputLayer</text>\n",
       "<polyline fill=\"none\" points=\"181.2383,-243.5 181.2383,-287.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"209.0728\" y=\"-272.3\">input:</text>\n",
       "<polyline fill=\"none\" points=\"181.2383,-265.5 236.9072,-265.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"209.0728\" y=\"-250.3\">output:</text>\n",
       "<polyline fill=\"none\" points=\"236.9072,-243.5 236.9072,-287.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"278.7314\" y=\"-272.3\">(None, 200)</text>\n",
       "<polyline fill=\"none\" points=\"236.9072,-265.5 320.5557,-265.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"278.7314\" y=\"-250.3\">(None, 200)</text>\n",
       "</g>\n",
       "<!-- 5465377536 -->\n",
       "<g class=\"node\" id=\"node2\">\n",
       "<title>5465377536</title>\n",
       "<polygon fill=\"none\" points=\"31.4932,-162.5 31.4932,-206.5 289.0625,-206.5 289.0625,-162.5 31.4932,-162.5\" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"90.6191\" y=\"-180.3\">dense_220: Dense</text>\n",
       "<polyline fill=\"none\" points=\"149.7451,-162.5 149.7451,-206.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"177.5796\" y=\"-191.3\">input:</text>\n",
       "<polyline fill=\"none\" points=\"149.7451,-184.5 205.4141,-184.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"177.5796\" y=\"-169.3\">output:</text>\n",
       "<polyline fill=\"none\" points=\"205.4141,-162.5 205.4141,-206.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"247.2383\" y=\"-191.3\">(None, 200)</text>\n",
       "<polyline fill=\"none\" points=\"205.4141,-184.5 289.0625,-184.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"247.2383\" y=\"-169.3\">(None, 300)</text>\n",
       "</g>\n",
       "<!-- 5465377648&#45;&gt;5465377536 -->\n",
       "<g class=\"edge\" id=\"edge1\">\n",
       "<title>5465377648-&gt;5465377536</title>\n",
       "<path d=\"M160.2778,-243.3664C160.2778,-235.1516 160.2778,-225.6579 160.2778,-216.7252\" fill=\"none\" stroke=\"#000000\"/>\n",
       "<polygon fill=\"#000000\" points=\"163.7779,-216.6068 160.2778,-206.6068 156.7779,-216.6069 163.7779,-216.6068\" stroke=\"#000000\"/>\n",
       "</g>\n",
       "<!-- 5465274800 -->\n",
       "<g class=\"node\" id=\"node3\">\n",
       "<title>5465274800</title>\n",
       "<polygon fill=\"none\" points=\"31.4932,-81.5 31.4932,-125.5 289.0625,-125.5 289.0625,-81.5 31.4932,-81.5\" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"90.6191\" y=\"-99.3\">dense_221: Dense</text>\n",
       "<polyline fill=\"none\" points=\"149.7451,-81.5 149.7451,-125.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"177.5796\" y=\"-110.3\">input:</text>\n",
       "<polyline fill=\"none\" points=\"149.7451,-103.5 205.4141,-103.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"177.5796\" y=\"-88.3\">output:</text>\n",
       "<polyline fill=\"none\" points=\"205.4141,-81.5 205.4141,-125.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"247.2383\" y=\"-110.3\">(None, 300)</text>\n",
       "<polyline fill=\"none\" points=\"205.4141,-103.5 289.0625,-103.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"247.2383\" y=\"-88.3\">(None, 300)</text>\n",
       "</g>\n",
       "<!-- 5465377536&#45;&gt;5465274800 -->\n",
       "<g class=\"edge\" id=\"edge2\">\n",
       "<title>5465377536-&gt;5465274800</title>\n",
       "<path d=\"M160.2778,-162.3664C160.2778,-154.1516 160.2778,-144.6579 160.2778,-135.7252\" fill=\"none\" stroke=\"#000000\"/>\n",
       "<polygon fill=\"#000000\" points=\"163.7779,-135.6068 160.2778,-125.6068 156.7779,-135.6069 163.7779,-135.6068\" stroke=\"#000000\"/>\n",
       "</g>\n",
       "<!-- 5465211232 -->\n",
       "<g class=\"node\" id=\"node4\">\n",
       "<title>5465211232</title>\n",
       "<polygon fill=\"none\" points=\"31.4932,-.5 31.4932,-44.5 289.0625,-44.5 289.0625,-.5 31.4932,-.5\" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"90.6191\" y=\"-18.3\">dense_222: Dense</text>\n",
       "<polyline fill=\"none\" points=\"149.7451,-.5 149.7451,-44.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"177.5796\" y=\"-29.3\">input:</text>\n",
       "<polyline fill=\"none\" points=\"149.7451,-22.5 205.4141,-22.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"177.5796\" y=\"-7.3\">output:</text>\n",
       "<polyline fill=\"none\" points=\"205.4141,-.5 205.4141,-44.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"247.2383\" y=\"-29.3\">(None, 300)</text>\n",
       "<polyline fill=\"none\" points=\"205.4141,-22.5 289.0625,-22.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"247.2383\" y=\"-7.3\">(None, 2)</text>\n",
       "</g>\n",
       "<!-- 5465274800&#45;&gt;5465211232 -->\n",
       "<g class=\"edge\" id=\"edge3\">\n",
       "<title>5465274800-&gt;5465211232</title>\n",
       "<path d=\"M160.2778,-81.3664C160.2778,-73.1516 160.2778,-63.6579 160.2778,-54.7252\" fill=\"none\" stroke=\"#000000\"/>\n",
       "<polygon fill=\"#000000\" points=\"163.7779,-54.6068 160.2778,-44.6068 156.7779,-54.6069 163.7779,-54.6068\" stroke=\"#000000\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>"
      ],
      "text/plain": [
       "<IPython.core.display.SVG object>"
      ]
     },
     "execution_count": 103,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model = create_model(300, 300, preamble_train.shape[1], channel_train.shape[1])\n",
    "SVG(model_to_dot(model, show_shapes=True, show_layer_names=True).create(prog='dot', format='svg'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 104,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/ipykernel_launcher.py:8: FutureWarning: `rcond` parameter will change to the default of machine precision times ``max(M, N)`` where M and N are the input matrix dimensions.\n",
      "To use the future default and silence this warning we advise to pass `rcond=None`, to keep using the old, explicitly pass `rcond=-1`.\n",
      "  \n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.00015076780306240052\n"
     ]
    }
   ],
   "source": [
    "def generate_topleitz(row_vector, channel_length):\n",
    "    from scipy import linalg as la\n",
    "    first_row = row_vector[:channel_length]\n",
    "    first_col = row_vector\n",
    "    return la.toeplitz(first_col, first_row)\n",
    "\n",
    "def least_squares(A, b):\n",
    "    return np.linalg.lstsq(A, b)[0]\n",
    "\n",
    "def perform_least_squares(preamble, preamble_convolved, channel_length):\n",
    "    A, b = generate_topleitz(preamble, channel_length), preamble_convolved\n",
    "    prediction = least_squares(A, b)\n",
    "    return np.array(prediction)\n",
    "\n",
    "def run_least_squares_channel_est(preambles, preambles_convolved, channels):\n",
    "    errors = []\n",
    "    for preamble, preamble_convolved, channel in zip(preambles, preambles_convolved, channels):\n",
    "        channel_estimate = np.real(perform_least_squares(preamble, preamble_convolved, channels.shape[1]))\n",
    "        errors.append(mean_squared_error(channel, channel_estimate))\n",
    "    return np.mean(np.array(errors))\n",
    "        \n",
    "\n",
    "error_lst_squares = run_least_squares_channel_est(lstsq_preambles, lstsq_preamble_convolved, channels)\n",
    "print(error_lst_squares)\n",
    "# print(predictions_least_squares)\n",
    "# print(channel_test)\n",
    "# mse = mean_squared_error(predictions_least_squares, channel_test)\n",
    "# mabse = mean_absolute_error(predictions_least_squares, channel_test)\n",
    "# print('Mean Squared Error: {0}'.format(mse))\n",
    "# print('Mean Absolute Error: {0}'.format(mabse))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 108,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Preamble length: 20\n",
      "Generated data\n",
      "Error NN: 4.754407906439155e-05\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/ipykernel_launcher.py:8: FutureWarning: `rcond` parameter will change to the default of machine precision times ``max(M, N)`` where M and N are the input matrix dimensions.\n",
      "To use the future default and silence this warning we advise to pass `rcond=None`, to keep using the old, explicitly pass `rcond=-1`.\n",
      "  \n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Error LSTSQ: 3.3957018369530616e+25\n",
      "Preamble length: 40\n",
      "Generated data\n",
      "Error NN: 0.004040335788577795\n",
      "Error LSTSQ: 0.000941029412518733\n",
      "Preamble length: 60\n",
      "Generated data\n",
      "Error NN: 0.004707991209626197\n",
      "Error LSTSQ: 0.00042014736153357814\n",
      "Preamble length: 80\n",
      "Generated data\n",
      "Error NN: 0.009021696710586547\n",
      "Error LSTSQ: 0.00023331364400975817\n",
      "Preamble length: 100\n",
      "Generated data\n",
      "Error NN: 0.013438218662142754\n",
      "Error LSTSQ: 0.00014950728863363872\n",
      "Preamble length: 120\n",
      "Generated data\n",
      "Error NN: 0.017218790954351425\n",
      "Error LSTSQ: 0.00010475193447906265\n",
      "Preamble length: 140\n",
      "Generated data\n",
      "Error NN: 0.016708977895975113\n",
      "Error LSTSQ: 7.696480009499078e-05\n",
      "Preamble length: 160\n",
      "Generated data\n",
      "Error NN: 0.020766299739480017\n",
      "Error LSTSQ: 5.82460430679427e-05\n",
      "Preamble length: 180\n",
      "Generated data\n",
      "Error NN: 0.022629045289754866\n",
      "Error LSTSQ: 4.650191001231202e-05\n",
      "Preamble length: 200\n",
      "Generated data\n",
      "Error NN: 0.026092957919836044\n",
      "Error LSTSQ: 3.7764953412524425e-05\n"
     ]
    }
   ],
   "source": [
    "def run_channel_estimation_experiment():\n",
    "    preamble_lengths = range(20, 201, 20)\n",
    "    errors = []\n",
    "    lstsq_errors = []\n",
    "    knn_errors = []\n",
    "    for preamble_length in preamble_lengths:\n",
    "        print('Preamble length:', preamble_length)\n",
    "        preamble_data, channels, lstsq_preambles, lstsq_preamble_convolved = generate_channel_estimation_dataset(50000, preamble_length, 4)\n",
    "        print('Generated data')\n",
    "        train_size = int(preamble_data.shape[0] * 0.8)\n",
    "        preamble_train, preamble_test = preamble_data[:train_size], preamble_data[train_size:]\n",
    "        channel_train, channel_test = channels[:train_size], channels[train_size:]\n",
    "        lstsq_preambles_test, lstsq_preambles_convolved_test = lstsq_preambles[train_size:], lstsq_preamble_convolved[train_size:]\n",
    "        model = create_model(300, 300, preamble_train.shape[1], channel_train.shape[1])\n",
    "        history = model.fit(preamble_train, channel_train, validation_data=(preamble_test, channel_test), epochs=100, batch_size=64, verbose=0)\n",
    "        error = history.history['val_loss'][-1]\n",
    "        errors.append(error)\n",
    "        print('Error NN:', error)\n",
    "        \n",
    "        error_lst_squares = run_least_squares_channel_est(lstsq_preambles_test, lstsq_preambles_convolved_test, channel_test)\n",
    "        print('Error LSTSQ:', error_lst_squares)\n",
    "        lstsq_errors.append(error_lst_squares)\n",
    "        \n",
    "        from sklearn.neighbors import KNeighborsRegressor\n",
    "        neigh = KNeighborsRegressor(n_neighbors=15)\n",
    "        neigh.fit(preamble_train, channel_train)\n",
    "        knn_predictions = neigh.fit(preamble_test)\n",
    "        error_knn = mean_squared_error(knn_predictions, channel_test)\n",
    "        print('Error knn', error_knn)\n",
    "        knn_errors.append(error_knn)\n",
    "        \n",
    "    return preamble_lengths, errors, lstsq_errors, knn_errors\n",
    "\n",
    "preamble_lengths, errors, lstsq_errors, knn_errors = run_channel_estimation_experiment()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 115,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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u0XHcNNNNzF58mSOOuooJkyYwMKFCxk3bhzHH3/81niuu+46DjzwQA488EC+//3vA7B8+XIOOOAAzjjjDD72sY+xevXqUv/ze4XJBw3nP04azfBBdQgYPqiO/zhpdKYdwB72al3hO458mufBPdNhc/oX2fqVyTbAmCndeqoLLriAo48+msMOO4zx48dzzjnnMGjQoIL1f/SjH3HxxRdz6qmn8s477xARPP3009xxxx0sXbqUd999l4aGBg499NC8Pz9r1ixuueUWIJnaZOHChQAsXryYJUuWMHjwYBYuXEhTUxPPP/88I0aM4KmnnmLu3Lk888wzbNmyhbFjxzJu3Djq6up48cUX+fnPf95td0TdoRpHC1XbSCEPe7WucOLI55GZ25JGq80bk/JuThznnHMOEyZM4IEHHmDBggXceOONLF26lP79++etf9hhh3HNNdfw6quvctJJJ7Hvvvvy+OOPc/LJJ1NXV0ddXR0nnHBCwfMVaqoaP348gwcP3rp96KGHMmLECCCZjr31+ACTJ0/md7/7HePHj2efffapuqRRjUNfq1G1JTOrHW6qymd9S2nlXTRs2DCmTp3KggUL6Nu3L88991zBul/84heZP38+/fv357jjjuPxxx/vlhh6ynTsHi1kVn5OHPnsXl9aeRc88MADbN68GYDXX3+ddevWMXx44b8CV6xYwb777st5553H8ccfT3NzM5/+9KeZP38+mzZtYsOGDdx7773dGuORRx7J/Pnz2bhxI3//+99ZsGABRx55ZLeeo7t4tJBZ+bmpKp9jrtq+jwOgX11S3gVvv/32dh3hF154IS0tLZx33nkMGDAASPog9tprr4LH+MUvfsFtt91Gv379GDZsGDNmzGDQoEGceOKJjBkzhj333JOxY8cW/PncPg6Ae+65p8O4x44dy+mnn84hhxwCwJe//GVGjx7N8uXLO/zZSvNoIbPy87TqhTTPS/o01rckdxrHXNXt/RvlcuWVVzJ06NB2h91WQhbTqrft44BktFDWo5jMqp2nVe8OY6bUTKKwbTxayKz8nDh6oGuuuSbrEDLl0UJm5ZVJ57ikWZJelNQsab6kvA8uSDpO0kuSlku6rKvn7YnNctXK19qs58pqVNXDwIERMQb4E3B52wqS+gA/BD4DHACcLumAzp5wwIABrFu3zr/QKiAiWLdu3dYOfzPrWTJp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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x14d6a6c88>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "preamble_lengths = list(range(40, 201, 20))\n",
    "plt.scatter(preamble_lengths, np.log10(errors[1:]), label='NN Error')\n",
    "plt.scatter(preamble_lengths, np.log10(lstsq_errors[1:]), label='LSTsq Error')\n",
    "plt.xlabel('preamble length')\n",
    "plt.ylabel('Log Error')\n",
    "plt.legend()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## One Tap Channel Inversion (Division)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 122,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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w/r162lqamLOnDmaHHxpaWnYuq8TEhKwWCzIskx/fz8LFy7E5/PR1dVFa2tr2GathxOHw0FdXR35+flMmzYtYA7g+PHj3HrrrRQVFfHee+9F1WtasmQJe/bsob29nby8PF588UWef/75Ycd8/etf59lnn2XZsmW8+uqrXHjhhXo+I5zEcMnR5H+KosR77713Sufn5+eTn5+vzSK45pprWL9+fTiWdkZhNBpZuHAhCxcu5M4770RRFJqamqiurubRRx+loaGBGTNmaEZkwYIFE97M/aVA/J/Yp06dCnypB9Xd3U1bWxsQ2qz1cKOOty0tLR1T52r79u2sWbOGn//851x99dVR34xNJhN/+MMfuPTSSzV12tLS0mHqtDfffDPXX389c+bMISMjgxdffDGqa9SZPPSSWz9WrlzJb3/724DVUytWrOCpp56isLCQdevW4XA4ePjhh6O8ytMbRVFobW3VZors2rWLadOmaTmR8vLyoDbziUiB+M9aj2bXujpHxe12U1paGtBIKorCn/70J/72t7/x3HPPMW/evIisRyeshL/kVqoUEEpVnN6nEXVef/11vv/979PV1UVaWhqLFi3i73//O4cPH2b16tW8/fbbAOzYsYPVq1fj8XiYPXs2f/7zn0lPT5/k1Z/eCCFob2/XRBh37NhBdnY2VVVVVFVVUVlZOay/IpxSILIsa81zkepadzqd7N69m5ycHAoKCgJ6DQMDA9x1113ExcXx2GOPTarEiU5I6EZjHM5IozGZHD9+nG9/+9vs27ePmTNn8vLLL49qiO69917eeustFEXhkksu4fe///0ZGUNWtaxqamqora1l+/btpKWlUVVVRUlJCX/961954IEHKC4uDnuyO9xd611dXbS1tY1b+tvU1MQtt9zCd7/7XVavXn1G/l3PYCJgNCoEfBrCGXG60TibuPfee8nIyOC+++5j/fr12Gw2fvOb3ww75pNPPuFHP/oRtbW1ACxfvpz//M//1HopzmSEEBw5coQNGzbw5JNPUlRUhCRJnHfeeaxYsYKlS5dGrIJtol3riqLQ1tbGwMAApaWlAcNeQghee+01HnnkEZ5++mkqKioi8j50IkoEjMZiAZtCOMOqd4SfTbzxxhtUV1cDcOONN7Jy5cqTjIYkSbhcLjweD0IIvF6vluw901H7Ndra2qirq2Pq1Kl0dnZSU1PD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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x1ea0faf28>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import sys\n",
    "\n",
    "import matplotlib\n",
    "import matplotlib.pyplot as plt\n",
    "from matplotlib.ticker import MaxNLocator\n",
    "from matplotlib import cm\n",
    "from mpl_toolkits.mplot3d import Axes3D\n",
    "\n",
    "import numpy\n",
    "from numpy.random import randn, shuffle\n",
    "from scipy import linspace, meshgrid, arange, empty, concatenate, newaxis, shape\n",
    "\n",
    "\n",
    "# =========================\n",
    "## generating ordered data:\n",
    "\n",
    "N = 32\n",
    "x = sorted(randn(N))\n",
    "y = sorted(randn(N))\n",
    "\n",
    "X, Y = meshgrid(x, y)\n",
    "Z = X / Y\n",
    "\n",
    "\n",
    "# ======================================\n",
    "## reference picture (X, Y and Z in 2D):\n",
    "\n",
    "fig = plt.figure()\n",
    "ax = fig.add_subplot(111, projection='3d')\n",
    "\n",
    "surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.jet, linewidth=0)\n",
    "fig.colorbar(surf)\n",
    "\n",
    "title = ax.set_title(\"plot_surface: given X, Y and Z as 2D:\")\n",
    "title.set_y(1.01)\n",
    "\n",
    "ax.xaxis.set_major_locator(MaxNLocator(5))\n",
    "ax.yaxis.set_major_locator(MaxNLocator(6))\n",
    "ax.zaxis.set_major_locator(MaxNLocator(5))\n",
    "\n",
    "fig.tight_layout()\n",
    "plt.savefig('Division_Function_plot.png', bbox_inches='tight')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {},
   "outputs": [],
   "source": [
    "def create_channel_inverse_model():\n",
    "    model_inverse = Sequential()\n",
    "    model_inverse.add(Dense(2, input_shape=(2,)))\n",
    "    model_inverse.add(Dense(50, activation='sigmoid'))\n",
    "    model_inverse.add(Dense(50, activation='sigmoid'))\n",
    "    model_inverse.add(Dense(1, activation='linear'))\n",
    "    model_inverse.compile(optimizer='adam',\n",
    "                  loss='mse',\n",
    "                  metrics=['mse'])\n",
    "    return model_inverse"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 102,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<svg height=\"377pt\" viewBox=\"0.00 0.00 314.56 377.00\" width=\"315pt\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g class=\"graph\" id=\"graph0\" transform=\"scale(1 1) rotate(0) translate(4 373)\">\n",
       "<title>G</title>\n",
       "<polygon fill=\"#ffffff\" points=\"-4,4 -4,-373 310.5557,-373 310.5557,4 -4,4\" stroke=\"transparent\"/>\n",
       "<!-- 5453168088 -->\n",
       "<g class=\"node\" id=\"node1\">\n",
       "<title>5453168088</title>\n",
       "<polygon fill=\"none\" points=\"0,-324.5 0,-368.5 306.5557,-368.5 306.5557,-324.5 0,-324.5\" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"90.6191\" y=\"-342.3\">dense_216_input: InputLayer</text>\n",
       "<polyline fill=\"none\" points=\"181.2383,-324.5 181.2383,-368.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"209.0728\" y=\"-353.3\">input:</text>\n",
       "<polyline fill=\"none\" points=\"181.2383,-346.5 236.9072,-346.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"209.0728\" y=\"-331.3\">output:</text>\n",
       "<polyline fill=\"none\" points=\"236.9072,-324.5 236.9072,-368.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"271.7314\" y=\"-353.3\">(None, 2)</text>\n",
       "<polyline fill=\"none\" points=\"236.9072,-346.5 306.5557,-346.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"271.7314\" y=\"-331.3\">(None, 2)</text>\n",
       "</g>\n",
       "<!-- 5453164616 -->\n",
       "<g class=\"node\" id=\"node2\">\n",
       "<title>5453164616</title>\n",
       "<polygon fill=\"none\" points=\"31.4932,-243.5 31.4932,-287.5 275.0625,-287.5 275.0625,-243.5 31.4932,-243.5\" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"90.6191\" y=\"-261.3\">dense_216: Dense</text>\n",
       "<polyline fill=\"none\" points=\"149.7451,-243.5 149.7451,-287.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"177.5796\" y=\"-272.3\">input:</text>\n",
       "<polyline fill=\"none\" points=\"149.7451,-265.5 205.4141,-265.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"177.5796\" y=\"-250.3\">output:</text>\n",
       "<polyline fill=\"none\" points=\"205.4141,-243.5 205.4141,-287.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"240.2383\" y=\"-272.3\">(None, 2)</text>\n",
       "<polyline fill=\"none\" points=\"205.4141,-265.5 275.0625,-265.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"240.2383\" y=\"-250.3\">(None, 2)</text>\n",
       "</g>\n",
       "<!-- 5453168088&#45;&gt;5453164616 -->\n",
       "<g class=\"edge\" id=\"edge1\">\n",
       "<title>5453168088-&gt;5453164616</title>\n",
       "<path d=\"M153.2778,-324.3664C153.2778,-316.1516 153.2778,-306.6579 153.2778,-297.7252\" fill=\"none\" stroke=\"#000000\"/>\n",
       "<polygon fill=\"#000000\" points=\"156.7779,-297.6068 153.2778,-287.6068 149.7779,-297.6069 156.7779,-297.6068\" stroke=\"#000000\"/>\n",
       "</g>\n",
       "<!-- 5434072088 -->\n",
       "<g class=\"node\" id=\"node3\">\n",
       "<title>5434072088</title>\n",
       "<polygon fill=\"none\" points=\"27.9932,-162.5 27.9932,-206.5 278.5625,-206.5 278.5625,-162.5 27.9932,-162.5\" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"87.1191\" y=\"-180.3\">dense_217: Dense</text>\n",
       "<polyline fill=\"none\" points=\"146.2451,-162.5 146.2451,-206.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"174.0796\" y=\"-191.3\">input:</text>\n",
       "<polyline fill=\"none\" points=\"146.2451,-184.5 201.9141,-184.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"174.0796\" y=\"-169.3\">output:</text>\n",
       "<polyline fill=\"none\" points=\"201.9141,-162.5 201.9141,-206.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"240.2383\" y=\"-191.3\">(None, 2)</text>\n",
       "<polyline fill=\"none\" points=\"201.9141,-184.5 278.5625,-184.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"240.2383\" y=\"-169.3\">(None, 50)</text>\n",
       "</g>\n",
       "<!-- 5453164616&#45;&gt;5434072088 -->\n",
       "<g class=\"edge\" id=\"edge2\">\n",
       "<title>5453164616-&gt;5434072088</title>\n",
       "<path d=\"M153.2778,-243.3664C153.2778,-235.1516 153.2778,-225.6579 153.2778,-216.7252\" fill=\"none\" stroke=\"#000000\"/>\n",
       "<polygon fill=\"#000000\" points=\"156.7779,-216.6068 153.2778,-206.6068 149.7779,-216.6069 156.7779,-216.6068\" stroke=\"#000000\"/>\n",
       "</g>\n",
       "<!-- 5453168424 -->\n",
       "<g class=\"node\" id=\"node4\">\n",
       "<title>5453168424</title>\n",
       "<polygon fill=\"none\" points=\"27.9932,-81.5 27.9932,-125.5 278.5625,-125.5 278.5625,-81.5 27.9932,-81.5\" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"87.1191\" y=\"-99.3\">dense_218: Dense</text>\n",
       "<polyline fill=\"none\" points=\"146.2451,-81.5 146.2451,-125.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"174.0796\" y=\"-110.3\">input:</text>\n",
       "<polyline fill=\"none\" points=\"146.2451,-103.5 201.9141,-103.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"174.0796\" y=\"-88.3\">output:</text>\n",
       "<polyline fill=\"none\" points=\"201.9141,-81.5 201.9141,-125.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"240.2383\" y=\"-110.3\">(None, 50)</text>\n",
       "<polyline fill=\"none\" points=\"201.9141,-103.5 278.5625,-103.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"240.2383\" y=\"-88.3\">(None, 50)</text>\n",
       "</g>\n",
       "<!-- 5434072088&#45;&gt;5453168424 -->\n",
       "<g class=\"edge\" id=\"edge3\">\n",
       "<title>5434072088-&gt;5453168424</title>\n",
       "<path d=\"M153.2778,-162.3664C153.2778,-154.1516 153.2778,-144.6579 153.2778,-135.7252\" fill=\"none\" stroke=\"#000000\"/>\n",
       "<polygon fill=\"#000000\" points=\"156.7779,-135.6068 153.2778,-125.6068 149.7779,-135.6069 156.7779,-135.6068\" stroke=\"#000000\"/>\n",
       "</g>\n",
       "<!-- 5463595216 -->\n",
       "<g class=\"node\" id=\"node5\">\n",
       "<title>5463595216</title>\n",
       "<polygon fill=\"none\" points=\"27.9932,-.5 27.9932,-44.5 278.5625,-44.5 278.5625,-.5 27.9932,-.5\" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"87.1191\" y=\"-18.3\">dense_219: Dense</text>\n",
       "<polyline fill=\"none\" points=\"146.2451,-.5 146.2451,-44.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"174.0796\" y=\"-29.3\">input:</text>\n",
       "<polyline fill=\"none\" points=\"146.2451,-22.5 201.9141,-22.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"174.0796\" y=\"-7.3\">output:</text>\n",
       "<polyline fill=\"none\" points=\"201.9141,-.5 201.9141,-44.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"240.2383\" y=\"-29.3\">(None, 50)</text>\n",
       "<polyline fill=\"none\" points=\"201.9141,-22.5 278.5625,-22.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"240.2383\" y=\"-7.3\">(None, 1)</text>\n",
       "</g>\n",
       "<!-- 5453168424&#45;&gt;5463595216 -->\n",
       "<g class=\"edge\" id=\"edge4\">\n",
       "<title>5453168424-&gt;5463595216</title>\n",
       "<path d=\"M153.2778,-81.3664C153.2778,-73.1516 153.2778,-63.6579 153.2778,-54.7252\" fill=\"none\" stroke=\"#000000\"/>\n",
       "<polygon fill=\"#000000\" points=\"156.7779,-54.6068 153.2778,-44.6068 149.7779,-54.6069 156.7779,-54.6068\" stroke=\"#000000\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>"
      ],
      "text/plain": [
       "<IPython.core.display.SVG object>"
      ]
     },
     "execution_count": 102,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from IPython.display import SVG\n",
    "from keras.utils.vis_utils import model_to_dot\n",
    "model_inverse = create_channel_inverse_model()\n",
    "SVG(model_to_dot(model_inverse, show_shapes=True, show_layer_names=True).create(prog='dot', format='svg'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "metadata": {},
   "outputs": [],
   "source": [
    "def generate_one_tap_channel_inversion_data(dataset_size, channel_lower_bound):\n",
    "    data_X = []\n",
    "    Y = []\n",
    "    for i in range(dataset_size):\n",
    "        data = np.random.uniform(-1, 1)\n",
    "        channel = np.random.uniform(channel_lower_bound, 1)\n",
    "        data_X.append([data, channel])\n",
    "        Y.append(data / channel)\n",
    "\n",
    "    X, Y = np.array(data_X), np.array(Y)\n",
    "    train_size = int(0.8 * dataset_size)\n",
    "    X_train, Y_train, X_test, Y_test = X[:train_size], Y[:train_size], X[train_size:], Y[train_size:]\n",
    "    return X_train, Y_train, X_test, Y_test\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0\n",
      "0\n",
      "1\n",
      "2\n",
      "3\n",
      "4\n",
      "0.01\n",
      "0\n",
      "1\n",
      "2\n",
      "3\n",
      "4\n",
      "0.05\n",
      "0\n",
      "1\n",
      "2\n",
      "3\n",
      "4\n",
      "0.1\n",
      "0\n",
      "1\n",
      "2\n",
      "3\n",
      "4\n",
      "0.2\n",
      "0\n",
      "1\n",
      "2\n",
      "3\n",
      "4\n",
      "0.3\n",
      "0\n",
      "1\n",
      "2\n",
      "3\n",
      "4\n",
      "0.4\n",
      "0\n",
      "1\n",
      "2\n",
      "3\n",
      "4\n",
      "0.5\n",
      "0\n",
      "1\n",
      "2\n",
      "3\n",
      "4\n",
      "[0, 0.01, 0.05, 0.1, 0.2, 0.3, 0.4, 0.5]\n",
      "[4220.708897505438, 1.2571276032953524, 0.0029150321228429673, 0.00042879482945427304, 6.490642346034293e-05, 4.962954599759541e-05, 6.527368150418625e-05, 0.00029157309302827345]\n"
     ]
    }
   ],
   "source": [
    "def run_varying_channel_lower_bound_experiment():\n",
    "    lower_bounds = [0, 0.01, 0.05, 0.1, 0.2, 0.3, 0.4, 0.5]\n",
    "    errors = []\n",
    "    for channel_lower_bound in lower_bounds:\n",
    "        avg_error = []\n",
    "        print(channel_lower_bound)\n",
    "        for trial in range(5):\n",
    "            print(trial)\n",
    "            X_train, Y_train, X_test, Y_test = generate_one_tap_channel_inversion_data(10000, channel_lower_bound)\n",
    "            model_inverse = create_channel_inverse_model()\n",
    "            history = model_inverse.fit(X_train, Y_train, validation_data=(X_test, Y_test), epochs=100, batch_size=64, verbose=0)\n",
    "            error = history.history['val_loss'][-1]\n",
    "            avg_error.append(error)\n",
    "        errors.append(sum(avg_error) / 5)\n",
    "    return lower_bounds, errors\n",
    "\n",
    "\n",
    "lower_bounds, errors = run_varying_channel_lower_bound_experiment()        \n",
    "print(lower_bounds)\n",
    "print(errors)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 79,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x15ff56588>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(lower_bounds, np.log10(errors))\n",
    "plt.xlabel('Lower bound on channel tap')\n",
    "plt.ylabel('Log error')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 79,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0\n",
      "0\n",
      "Error: 4.957385820207258e-14\n",
      "1\n",
      "Error: 1.5276960930012475e-14\n",
      "2\n",
      "Error: 8.537100995749392e-14\n",
      "3\n",
      "Error: 3.229858010308817e-05\n",
      "4\n",
      "Error: 1.9588047412980815e-05\n",
      "0.01\n",
      "0\n",
      "Error: 1.5806054002535236e-14\n",
      "1\n",
      "Error: 5.686233817137065e-12\n",
      "2\n",
      "Error: 3.1305491011990317e-13\n",
      "3\n",
      "Error: 1.4746391524544932e-11\n",
      "4\n",
      "Error: 6.314194186415989e-06\n",
      "0.05\n",
      "0\n",
      "Error: 1.1757015771097362e-14\n",
      "1\n",
      "Error: 7.187668760177956e-11\n",
      "2\n",
      "Error: 6.913555557035155e-14\n",
      "3\n",
      "Error: 5.089352110854151e-10\n",
      "4\n",
      "Error: 1.8558657860490157e-11\n",
      "0.1\n",
      "0\n",
      "Error: 1.1154165330089227e-13\n",
      "1\n",
      "Error: 2.506014559912728e-06\n",
      "2\n",
      "Error: 3.5123717961882404e-12\n",
      "3\n",
      "Error: 1.057217711775138e-08\n",
      "4\n",
      "Error: 9.312002368202024e-15\n",
      "0.2\n",
      "0\n",
      "Error: 2.6473193700127933e-14\n",
      "1\n",
      "Error: 9.368030873604938e-15\n",
      "2\n",
      "Error: 1.2097627825717606e-13\n",
      "3\n",
      "Error: 4.964588344869015e-10\n",
      "4\n",
      "Error: 1.3766903972367573e-09\n",
      "0.3\n",
      "0\n",
      "Error: 0.00012961585097946227\n",
      "1\n",
      "Error: 5.310332184291048e-15\n",
      "2\n",
      "Error: 9.536901256979036e-08\n",
      "3\n",
      "Error: 2.567167885717936e-05\n",
      "4\n",
      "Error: 1.1365786214750581e-14\n",
      "0.4\n",
      "0\n",
      "Error: 8.655903142688882e-15\n",
      "1\n",
      "Error: 1.6883345915630342e-07\n",
      "2\n",
      "Error: 5.957313369719941e-09\n",
      "3\n",
      "Error: 5.952378046458762e-09\n",
      "4\n",
      "Error: 3.8678517921653113e-07\n",
      "0.5\n",
      "0\n",
      "Error: 6.873565850881464e-15\n",
      "1\n",
      "Error: 6.590792564487025e-13\n",
      "2\n",
      "Error: 1.1846670291883882e-14\n",
      "3\n",
      "Error: 8.467235213752838e-15\n",
      "4\n",
      "Error: 1.2376093476863108e-14\n"
     ]
    }
   ],
   "source": [
    "def create_channel_inverse_model():\n",
    "    model_inverse = Sequential()\n",
    "    model_inverse.add(Dense(2, input_shape=(2,)))\n",
    "    model_inverse.add(Dense(50, activation='sigmoid'))\n",
    "    model_inverse.add(Dense(50, activation='sigmoid'))\n",
    "    model_inverse.add(Dense(1, activation='linear'))\n",
    "    model_inverse.compile(optimizer='adam',\n",
    "                  loss='mse',\n",
    "                  metrics=['mse'])\n",
    "    return model_inverse\n",
    "\n",
    "def generate_channel_inversion_one_tap_log_features(dataset_size, channel_lower_bound):\n",
    "    data_X = []\n",
    "    Y = []\n",
    "    for i in range(dataset_size):\n",
    "        data = np.random.uniform(0.1, 1)\n",
    "        channel = np.random.uniform(channel_lower_bound, 1)\n",
    "        data_X.append([data, channel])\n",
    "        Y.append(data / channel)\n",
    "\n",
    "    X, Y = np.log(np.array(data_X)), np.log(np.array(Y))\n",
    "\n",
    "    train_size = int(0.8 * dataset_size)\n",
    "    X_train, Y_train, X_test, Y_test = X[:train_size], Y[:train_size], X[train_size:], Y[train_size:]\n",
    "    return X_train, Y_train, X_test, Y_test\n",
    "\n",
    "def run_varying_channel_lower_bound_experiment_log_features():\n",
    "    lower_bounds = [0, 0.01, 0.05, 0.1, 0.2, 0.3, 0.4, 0.5]\n",
    "    errors = []\n",
    "    for channel_lower_bound in lower_bounds:\n",
    "        avg_error = []\n",
    "        print(channel_lower_bound)\n",
    "        for trial in range(5):\n",
    "            print(trial)\n",
    "            X_train, Y_train, X_test, Y_test = generate_channel_inversion_one_tap_log_features(10000, channel_lower_bound)\n",
    "            model_inverse = create_channel_inverse_model_log()\n",
    "            history = model_inverse.fit(X_train, Y_train, validation_data=(X_test, Y_test), epochs=100, batch_size=64, verbose=0)\n",
    "            error = history.history['val_loss'][-1]\n",
    "            print('Error: {0}'.format(error))\n",
    "            avg_error.append(error)\n",
    "        errors.append(sum(avg_error) / 5)\n",
    "    return lower_bounds, errors\n",
    "\n",
    "lower_bounds, errors = run_varying_channel_lower_bound_experiment_log_features()  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 89,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/javascript": [
       "/* Put everything inside the global mpl namespace */\n",
       "window.mpl = {};\n",
       "\n",
       "\n",
       "mpl.get_websocket_type = function() {\n",
       "    if (typeof(WebSocket) !== 'undefined') {\n",
       "        return WebSocket;\n",
       "    } else if (typeof(MozWebSocket) !== 'undefined') {\n",
       "        return MozWebSocket;\n",
       "    } else {\n",
       "        alert('Your browser does not have WebSocket support.' +\n",
       "              'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
       "              'Firefox 4 and 5 are also supported but you ' +\n",
       "              'have to enable WebSockets in about:config.');\n",
       "    };\n",
       "}\n",
       "\n",
       "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
       "    this.id = figure_id;\n",
       "\n",
       "    this.ws = websocket;\n",
       "\n",
       "    this.supports_binary = (this.ws.binaryType != undefined);\n",
       "\n",
       "    if (!this.supports_binary) {\n",
       "        var warnings = document.getElementById(\"mpl-warnings\");\n",
       "        if (warnings) {\n",
       "            warnings.style.display = 'block';\n",
       "            warnings.textContent = (\n",
       "                \"This browser does not support binary websocket messages. \" +\n",
       "                    \"Performance may be slow.\");\n",
       "        }\n",
       "    }\n",
       "\n",
       "    this.imageObj = new Image();\n",
       "\n",
       "    this.context = undefined;\n",
       "    this.message = undefined;\n",
       "    this.canvas = undefined;\n",
       "    this.rubberband_canvas = undefined;\n",
       "    this.rubberband_context = undefined;\n",
       "    this.format_dropdown = undefined;\n",
       "\n",
       "    this.image_mode = 'full';\n",
       "\n",
       "    this.root = $('<div/>');\n",
       "    this._root_extra_style(this.root)\n",
       "    this.root.attr('style', 'display: inline-block');\n",
       "\n",
       "    $(parent_element).append(this.root);\n",
       "\n",
       "    this._init_header(this);\n",
       "    this._init_canvas(this);\n",
       "    this._init_toolbar(this);\n",
       "\n",
       "    var fig = this;\n",
       "\n",
       "    this.waiting = false;\n",
       "\n",
       "    this.ws.onopen =  function () {\n",
       "            fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
       "            fig.send_message(\"send_image_mode\", {});\n",
       "            if (mpl.ratio != 1) {\n",
       "                fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
       "            }\n",
       "            fig.send_message(\"refresh\", {});\n",
       "        }\n",
       "\n",
       "    this.imageObj.onload = function() {\n",
       "            if (fig.image_mode == 'full') {\n",
       "                // Full images could contain transparency (where diff images\n",
       "                // almost always do), so we need to clear the canvas so that\n",
       "                // there is no ghosting.\n",
       "                fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
       "            }\n",
       "            fig.context.drawImage(fig.imageObj, 0, 0);\n",
       "        };\n",
       "\n",
       "    this.imageObj.onunload = function() {\n",
       "        this.ws.close();\n",
       "    }\n",
       "\n",
       "    this.ws.onmessage = this._make_on_message_function(this);\n",
       "\n",
       "    this.ondownload = ondownload;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_header = function() {\n",
       "    var titlebar = $(\n",
       "        '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
       "        'ui-helper-clearfix\"/>');\n",
       "    var titletext = $(\n",
       "        '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
       "        'text-align: center; padding: 3px;\"/>');\n",
       "    titlebar.append(titletext)\n",
       "    this.root.append(titlebar);\n",
       "    this.header = titletext[0];\n",
       "}\n",
       "\n",
       "\n",
       "\n",
       "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
       "\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
       "\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_canvas = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var canvas_div = $('<div/>');\n",
       "\n",
       "    canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
       "\n",
       "    function canvas_keyboard_event(event) {\n",
       "        return fig.key_event(event, event['data']);\n",
       "    }\n",
       "\n",
       "    canvas_div.keydown('key_press', canvas_keyboard_event);\n",
       "    canvas_div.keyup('key_release', canvas_keyboard_event);\n",
       "    this.canvas_div = canvas_div\n",
       "    this._canvas_extra_style(canvas_div)\n",
       "    this.root.append(canvas_div);\n",
       "\n",
       "    var canvas = $('<canvas/>');\n",
       "    canvas.addClass('mpl-canvas');\n",
       "    canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
       "\n",
       "    this.canvas = canvas[0];\n",
       "    this.context = canvas[0].getContext(\"2d\");\n",
       "\n",
       "    var backingStore = this.context.backingStorePixelRatio ||\n",
       "\tthis.context.webkitBackingStorePixelRatio ||\n",
       "\tthis.context.mozBackingStorePixelRatio ||\n",
       "\tthis.context.msBackingStorePixelRatio ||\n",
       "\tthis.context.oBackingStorePixelRatio ||\n",
       "\tthis.context.backingStorePixelRatio || 1;\n",
       "\n",
       "    mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
       "\n",
       "    var rubberband = $('<canvas/>');\n",
       "    rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
       "\n",
       "    var pass_mouse_events = true;\n",
       "\n",
       "    canvas_div.resizable({\n",
       "        start: function(event, ui) {\n",
       "            pass_mouse_events = false;\n",
       "        },\n",
       "        resize: function(event, ui) {\n",
       "            fig.request_resize(ui.size.width, ui.size.height);\n",
       "        },\n",
       "        stop: function(event, ui) {\n",
       "            pass_mouse_events = true;\n",
       "            fig.request_resize(ui.size.width, ui.size.height);\n",
       "        },\n",
       "    });\n",
       "\n",
       "    function mouse_event_fn(event) {\n",
       "        if (pass_mouse_events)\n",
       "            return fig.mouse_event(event, event['data']);\n",
       "    }\n",
       "\n",
       "    rubberband.mousedown('button_press', mouse_event_fn);\n",
       "    rubberband.mouseup('button_release', mouse_event_fn);\n",
       "    // Throttle sequential mouse events to 1 every 20ms.\n",
       "    rubberband.mousemove('motion_notify', mouse_event_fn);\n",
       "\n",
       "    rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
       "    rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
       "\n",
       "    canvas_div.on(\"wheel\", function (event) {\n",
       "        event = event.originalEvent;\n",
       "        event['data'] = 'scroll'\n",
       "        if (event.deltaY < 0) {\n",
       "            event.step = 1;\n",
       "        } else {\n",
       "            event.step = -1;\n",
       "        }\n",
       "        mouse_event_fn(event);\n",
       "    });\n",
       "\n",
       "    canvas_div.append(canvas);\n",
       "    canvas_div.append(rubberband);\n",
       "\n",
       "    this.rubberband = rubberband;\n",
       "    this.rubberband_canvas = rubberband[0];\n",
       "    this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
       "    this.rubberband_context.strokeStyle = \"#000000\";\n",
       "\n",
       "    this._resize_canvas = function(width, height) {\n",
       "        // Keep the size of the canvas, canvas container, and rubber band\n",
       "        // canvas in synch.\n",
       "        canvas_div.css('width', width)\n",
       "        canvas_div.css('height', height)\n",
       "\n",
       "        canvas.attr('width', width * mpl.ratio);\n",
       "        canvas.attr('height', height * mpl.ratio);\n",
       "        canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
       "\n",
       "        rubberband.attr('width', width);\n",
       "        rubberband.attr('height', height);\n",
       "    }\n",
       "\n",
       "    // Set the figure to an initial 600x600px, this will subsequently be updated\n",
       "    // upon first draw.\n",
       "    this._resize_canvas(600, 600);\n",
       "\n",
       "    // Disable right mouse context menu.\n",
       "    $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
       "        return false;\n",
       "    });\n",
       "\n",
       "    function set_focus () {\n",
       "        canvas.focus();\n",
       "        canvas_div.focus();\n",
       "    }\n",
       "\n",
       "    window.setTimeout(set_focus, 100);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_toolbar = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var nav_element = $('<div/>')\n",
       "    nav_element.attr('style', 'width: 100%');\n",
       "    this.root.append(nav_element);\n",
       "\n",
       "    // Define a callback function for later on.\n",
       "    function toolbar_event(event) {\n",
       "        return fig.toolbar_button_onclick(event['data']);\n",
       "    }\n",
       "    function toolbar_mouse_event(event) {\n",
       "        return fig.toolbar_button_onmouseover(event['data']);\n",
       "    }\n",
       "\n",
       "    for(var toolbar_ind in mpl.toolbar_items) {\n",
       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
       "\n",
       "        if (!name) {\n",
       "            // put a spacer in here.\n",
       "            continue;\n",
       "        }\n",
       "        var button = $('<button/>');\n",
       "        button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
       "                        'ui-button-icon-only');\n",
       "        button.attr('role', 'button');\n",
       "        button.attr('aria-disabled', 'false');\n",
       "        button.click(method_name, toolbar_event);\n",
       "        button.mouseover(tooltip, toolbar_mouse_event);\n",
       "\n",
       "        var icon_img = $('<span/>');\n",
       "        icon_img.addClass('ui-button-icon-primary ui-icon');\n",
       "        icon_img.addClass(image);\n",
       "        icon_img.addClass('ui-corner-all');\n",
       "\n",
       "        var tooltip_span = $('<span/>');\n",
       "        tooltip_span.addClass('ui-button-text');\n",
       "        tooltip_span.html(tooltip);\n",
       "\n",
       "        button.append(icon_img);\n",
       "        button.append(tooltip_span);\n",
       "\n",
       "        nav_element.append(button);\n",
       "    }\n",
       "\n",
       "    var fmt_picker_span = $('<span/>');\n",
       "\n",
       "    var fmt_picker = $('<select/>');\n",
       "    fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
       "    fmt_picker_span.append(fmt_picker);\n",
       "    nav_element.append(fmt_picker_span);\n",
       "    this.format_dropdown = fmt_picker[0];\n",
       "\n",
       "    for (var ind in mpl.extensions) {\n",
       "        var fmt = mpl.extensions[ind];\n",
       "        var option = $(\n",
       "            '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
       "        fmt_picker.append(option)\n",
       "    }\n",
       "\n",
       "    // Add hover states to the ui-buttons\n",
       "    $( \".ui-button\" ).hover(\n",
       "        function() { $(this).addClass(\"ui-state-hover\");},\n",
       "        function() { $(this).removeClass(\"ui-state-hover\");}\n",
       "    );\n",
       "\n",
       "    var status_bar = $('<span class=\"mpl-message\"/>');\n",
       "    nav_element.append(status_bar);\n",
       "    this.message = status_bar[0];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
       "    // which will in turn request a refresh of the image.\n",
       "    this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.send_message = function(type, properties) {\n",
       "    properties['type'] = type;\n",
       "    properties['figure_id'] = this.id;\n",
       "    this.ws.send(JSON.stringify(properties));\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.send_draw_message = function() {\n",
       "    if (!this.waiting) {\n",
       "        this.waiting = true;\n",
       "        this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
       "    }\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
       "    var format_dropdown = fig.format_dropdown;\n",
       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
       "    fig.ondownload(fig, format);\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
       "    var size = msg['size'];\n",
       "    if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
       "        fig._resize_canvas(size[0], size[1]);\n",
       "        fig.send_message(\"refresh\", {});\n",
       "    };\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
       "    var x0 = msg['x0'] / mpl.ratio;\n",
       "    var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
       "    var x1 = msg['x1'] / mpl.ratio;\n",
       "    var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
       "    x0 = Math.floor(x0) + 0.5;\n",
       "    y0 = Math.floor(y0) + 0.5;\n",
       "    x1 = Math.floor(x1) + 0.5;\n",
       "    y1 = Math.floor(y1) + 0.5;\n",
       "    var min_x = Math.min(x0, x1);\n",
       "    var min_y = Math.min(y0, y1);\n",
       "    var width = Math.abs(x1 - x0);\n",
       "    var height = Math.abs(y1 - y0);\n",
       "\n",
       "    fig.rubberband_context.clearRect(\n",
       "        0, 0, fig.canvas.width, fig.canvas.height);\n",
       "\n",
       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
       "    // Updates the figure title.\n",
       "    fig.header.textContent = msg['label'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
       "    var cursor = msg['cursor'];\n",
       "    switch(cursor)\n",
       "    {\n",
       "    case 0:\n",
       "        cursor = 'pointer';\n",
       "        break;\n",
       "    case 1:\n",
       "        cursor = 'default';\n",
       "        break;\n",
       "    case 2:\n",
       "        cursor = 'crosshair';\n",
       "        break;\n",
       "    case 3:\n",
       "        cursor = 'move';\n",
       "        break;\n",
       "    }\n",
       "    fig.rubberband_canvas.style.cursor = cursor;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
       "    fig.message.textContent = msg['message'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
       "    // Request the server to send over a new figure.\n",
       "    fig.send_draw_message();\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
       "    fig.image_mode = msg['mode'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.updated_canvas_event = function() {\n",
       "    // Called whenever the canvas gets updated.\n",
       "    this.send_message(\"ack\", {});\n",
       "}\n",
       "\n",
       "// A function to construct a web socket function for onmessage handling.\n",
       "// Called in the figure constructor.\n",
       "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
       "    return function socket_on_message(evt) {\n",
       "        if (evt.data instanceof Blob) {\n",
       "            /* FIXME: We get \"Resource interpreted as Image but\n",
       "             * transferred with MIME type text/plain:\" errors on\n",
       "             * Chrome.  But how to set the MIME type?  It doesn't seem\n",
       "             * to be part of the websocket stream */\n",
       "            evt.data.type = \"image/png\";\n",
       "\n",
       "            /* Free the memory for the previous frames */\n",
       "            if (fig.imageObj.src) {\n",
       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
       "                    fig.imageObj.src);\n",
       "            }\n",
       "\n",
       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
       "                evt.data);\n",
       "            fig.updated_canvas_event();\n",
       "            fig.waiting = false;\n",
       "            return;\n",
       "        }\n",
       "        else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
       "            fig.imageObj.src = evt.data;\n",
       "            fig.updated_canvas_event();\n",
       "            fig.waiting = false;\n",
       "            return;\n",
       "        }\n",
       "\n",
       "        var msg = JSON.parse(evt.data);\n",
       "        var msg_type = msg['type'];\n",
       "\n",
       "        // Call the  \"handle_{type}\" callback, which takes\n",
       "        // the figure and JSON message as its only arguments.\n",
       "        try {\n",
       "            var callback = fig[\"handle_\" + msg_type];\n",
       "        } catch (e) {\n",
       "            console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
       "            return;\n",
       "        }\n",
       "\n",
       "        if (callback) {\n",
       "            try {\n",
       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
       "                callback(fig, msg);\n",
       "            } catch (e) {\n",
       "                console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
       "            }\n",
       "        }\n",
       "    };\n",
       "}\n",
       "\n",
       "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
       "mpl.findpos = function(e) {\n",
       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
       "    var targ;\n",
       "    if (!e)\n",
       "        e = window.event;\n",
       "    if (e.target)\n",
       "        targ = e.target;\n",
       "    else if (e.srcElement)\n",
       "        targ = e.srcElement;\n",
       "    if (targ.nodeType == 3) // defeat Safari bug\n",
       "        targ = targ.parentNode;\n",
       "\n",
       "    // jQuery normalizes the pageX and pageY\n",
       "    // pageX,Y are the mouse positions relative to the document\n",
       "    // offset() returns the position of the element relative to the document\n",
       "    var x = e.pageX - $(targ).offset().left;\n",
       "    var y = e.pageY - $(targ).offset().top;\n",
       "\n",
       "    return {\"x\": x, \"y\": y};\n",
       "};\n",
       "\n",
       "/*\n",
       " * return a copy of an object with only non-object keys\n",
       " * we need this to avoid circular references\n",
       " * http://stackoverflow.com/a/24161582/3208463\n",
       " */\n",
       "function simpleKeys (original) {\n",
       "  return Object.keys(original).reduce(function (obj, key) {\n",
       "    if (typeof original[key] !== 'object')\n",
       "        obj[key] = original[key]\n",
       "    return obj;\n",
       "  }, {});\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.mouse_event = function(event, name) {\n",
       "    var canvas_pos = mpl.findpos(event)\n",
       "\n",
       "    if (name === 'button_press')\n",
       "    {\n",
       "        this.canvas.focus();\n",
       "        this.canvas_div.focus();\n",
       "    }\n",
       "\n",
       "    var x = canvas_pos.x * mpl.ratio;\n",
       "    var y = canvas_pos.y * mpl.ratio;\n",
       "\n",
       "    this.send_message(name, {x: x, y: y, button: event.button,\n",
       "                             step: event.step,\n",
       "                             guiEvent: simpleKeys(event)});\n",
       "\n",
       "    /* This prevents the web browser from automatically changing to\n",
       "     * the text insertion cursor when the button is pressed.  We want\n",
       "     * to control all of the cursor setting manually through the\n",
       "     * 'cursor' event from matplotlib */\n",
       "    event.preventDefault();\n",
       "    return false;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
       "    // Handle any extra behaviour associated with a key event\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.key_event = function(event, name) {\n",
       "\n",
       "    // Prevent repeat events\n",
       "    if (name == 'key_press')\n",
       "    {\n",
       "        if (event.which === this._key)\n",
       "            return;\n",
       "        else\n",
       "            this._key = event.which;\n",
       "    }\n",
       "    if (name == 'key_release')\n",
       "        this._key = null;\n",
       "\n",
       "    var value = '';\n",
       "    if (event.ctrlKey && event.which != 17)\n",
       "        value += \"ctrl+\";\n",
       "    if (event.altKey && event.which != 18)\n",
       "        value += \"alt+\";\n",
       "    if (event.shiftKey && event.which != 16)\n",
       "        value += \"shift+\";\n",
       "\n",
       "    value += 'k';\n",
       "    value += event.which.toString();\n",
       "\n",
       "    this._key_event_extra(event, name);\n",
       "\n",
       "    this.send_message(name, {key: value,\n",
       "                             guiEvent: simpleKeys(event)});\n",
       "    return false;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
       "    if (name == 'download') {\n",
       "        this.handle_save(this, null);\n",
       "    } else {\n",
       "        this.send_message(\"toolbar_button\", {name: name});\n",
       "    }\n",
       "};\n",
       "\n",
       "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
       "    this.message.textContent = tooltip;\n",
       "};\n",
       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to  previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
       "\n",
       "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
       "\n",
       "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
       "    // object with the appropriate methods. Currently this is a non binary\n",
       "    // socket, so there is still some room for performance tuning.\n",
       "    var ws = {};\n",
       "\n",
       "    ws.close = function() {\n",
       "        comm.close()\n",
       "    };\n",
       "    ws.send = function(m) {\n",
       "        //console.log('sending', m);\n",
       "        comm.send(m);\n",
       "    };\n",
       "    // Register the callback with on_msg.\n",
       "    comm.on_msg(function(msg) {\n",
       "        //console.log('receiving', msg['content']['data'], msg);\n",
       "        // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
       "        ws.onmessage(msg['content']['data'])\n",
       "    });\n",
       "    return ws;\n",
       "}\n",
       "\n",
       "mpl.mpl_figure_comm = function(comm, msg) {\n",
       "    // This is the function which gets called when the mpl process\n",
       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
       "\n",
       "    var id = msg.content.data.id;\n",
       "    // Get hold of the div created by the display call when the Comm\n",
       "    // socket was opened in Python.\n",
       "    var element = $(\"#\" + id);\n",
       "    var ws_proxy = comm_websocket_adapter(comm)\n",
       "\n",
       "    function ondownload(figure, format) {\n",
       "        window.open(figure.imageObj.src);\n",
       "    }\n",
       "\n",
       "    var fig = new mpl.figure(id, ws_proxy,\n",
       "                           ondownload,\n",
       "                           element.get(0));\n",
       "\n",
       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
       "    // web socket which is closed, not our websocket->open comm proxy.\n",
       "    ws_proxy.onopen();\n",
       "\n",
       "    fig.parent_element = element.get(0);\n",
       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
       "    if (!fig.cell_info) {\n",
       "        console.error(\"Failed to find cell for figure\", id, fig);\n",
       "        return;\n",
       "    }\n",
       "\n",
       "    var output_index = fig.cell_info[2]\n",
       "    var cell = fig.cell_info[0];\n",
       "\n",
       "};\n",
       "\n",
       "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
       "    var width = fig.canvas.width/mpl.ratio\n",
       "    fig.root.unbind('remove')\n",
       "\n",
       "    // Update the output cell to use the data from the current canvas.\n",
       "    fig.push_to_output();\n",
       "    var dataURL = fig.canvas.toDataURL();\n",
       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
       "    // the notebook keyboard shortcuts fail.\n",
       "    IPython.keyboard_manager.enable()\n",
       "    $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
       "    fig.close_ws(fig, msg);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.close_ws = function(fig, msg){\n",
       "    fig.send_message('closing', msg);\n",
       "    // fig.ws.close()\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
       "    // Turn the data on the canvas into data in the output cell.\n",
       "    var width = this.canvas.width/mpl.ratio\n",
       "    var dataURL = this.canvas.toDataURL();\n",
       "    this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.updated_canvas_event = function() {\n",
       "    // Tell IPython that the notebook contents must change.\n",
       "    IPython.notebook.set_dirty(true);\n",
       "    this.send_message(\"ack\", {});\n",
       "    var fig = this;\n",
       "    // Wait a second, then push the new image to the DOM so\n",
       "    // that it is saved nicely (might be nice to debounce this).\n",
       "    setTimeout(function () { fig.push_to_output() }, 1000);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_toolbar = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var nav_element = $('<div/>')\n",
       "    nav_element.attr('style', 'width: 100%');\n",
       "    this.root.append(nav_element);\n",
       "\n",
       "    // Define a callback function for later on.\n",
       "    function toolbar_event(event) {\n",
       "        return fig.toolbar_button_onclick(event['data']);\n",
       "    }\n",
       "    function toolbar_mouse_event(event) {\n",
       "        return fig.toolbar_button_onmouseover(event['data']);\n",
       "    }\n",
       "\n",
       "    for(var toolbar_ind in mpl.toolbar_items){\n",
       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
       "\n",
       "        if (!name) { continue; };\n",
       "\n",
       "        var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
       "        button.click(method_name, toolbar_event);\n",
       "        button.mouseover(tooltip, toolbar_mouse_event);\n",
       "        nav_element.append(button);\n",
       "    }\n",
       "\n",
       "    // Add the status bar.\n",
       "    var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
       "    nav_element.append(status_bar);\n",
       "    this.message = status_bar[0];\n",
       "\n",
       "    // Add the close button to the window.\n",
       "    var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
       "    var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
       "    button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
       "    button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
       "    buttongrp.append(button);\n",
       "    var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
       "    titlebar.prepend(buttongrp);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._root_extra_style = function(el){\n",
       "    var fig = this\n",
       "    el.on(\"remove\", function(){\n",
       "\tfig.close_ws(fig, {});\n",
       "    });\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._canvas_extra_style = function(el){\n",
       "    // this is important to make the div 'focusable\n",
       "    el.attr('tabindex', 0)\n",
       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
       "    // off when our div gets focus\n",
       "\n",
       "    // location in version 3\n",
       "    if (IPython.notebook.keyboard_manager) {\n",
       "        IPython.notebook.keyboard_manager.register_events(el);\n",
       "    }\n",
       "    else {\n",
       "        // location in version 2\n",
       "        IPython.keyboard_manager.register_events(el);\n",
       "    }\n",
       "\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
       "    var manager = IPython.notebook.keyboard_manager;\n",
       "    if (!manager)\n",
       "        manager = IPython.keyboard_manager;\n",
       "\n",
       "    // Check for shift+enter\n",
       "    if (event.shiftKey && event.which == 13) {\n",
       "        this.canvas_div.blur();\n",
       "        // select the cell after this one\n",
       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
       "        IPython.notebook.select(index + 1);\n",
       "    }\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
       "    fig.ondownload(fig, null);\n",
       "}\n",
       "\n",
       "\n",
       "mpl.find_output_cell = function(html_output) {\n",
       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
       "    // IPython event is triggered only after the cells have been serialised, which for\n",
       "    // our purposes (turning an active figure into a static one), is too late.\n",
       "    var cells = IPython.notebook.get_cells();\n",
       "    var ncells = cells.length;\n",
       "    for (var i=0; i<ncells; i++) {\n",
       "        var cell = cells[i];\n",
       "        if (cell.cell_type === 'code'){\n",
       "            for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
       "                var data = cell.output_area.outputs[j];\n",
       "                if (data.data) {\n",
       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
       "                    data = data.data;\n",
       "                }\n",
       "                if (data['text/html'] == html_output) {\n",
       "                    return [cell, data, j];\n",
       "                }\n",
       "            }\n",
       "        }\n",
       "    }\n",
       "}\n",
       "\n",
       "// Register the function which deals with the matplotlib target/channel.\n",
       "// The kernel may be null if the page has been refreshed.\n",
       "if (IPython.notebook.kernel != null) {\n",
       "    IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
       "}\n"
      ],
      "text/plain": [
       "<IPython.core.display.Javascript object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<img src=\"\" width=\"432\">"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(lower_bounds, np.log10(errors))\n",
    "plt.xlabel('Lower bound on channel tap')\n",
    "plt.ylabel('Log error')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Network for Multiplication"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 116,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x1ea0786a0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import sys\n",
    "\n",
    "import matplotlib\n",
    "import matplotlib.pyplot as plt\n",
    "from matplotlib.ticker import MaxNLocator\n",
    "from matplotlib import cm\n",
    "from mpl_toolkits.mplot3d import Axes3D\n",
    "\n",
    "import numpy\n",
    "from numpy.random import randn, shuffle\n",
    "from scipy import linspace, meshgrid, arange, empty, concatenate, newaxis, shape\n",
    "\n",
    "\n",
    "# =========================\n",
    "## generating ordered data:\n",
    "\n",
    "N = 32\n",
    "x = sorted(randn(N))\n",
    "y = sorted(randn(N))\n",
    "\n",
    "X, Y = meshgrid(x, y)\n",
    "Z = X * Y\n",
    "\n",
    "\n",
    "# ======================================\n",
    "## reference picture (X, Y and Z in 2D):\n",
    "\n",
    "fig = plt.figure()\n",
    "ax = fig.add_subplot(111, projection='3d')\n",
    "\n",
    "surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.jet, linewidth=0)\n",
    "fig.colorbar(surf)\n",
    "\n",
    "title = ax.set_title(\"plot_surface: given X, Y and Z as 2D:\")\n",
    "title.set_y(1.01)\n",
    "\n",
    "ax.xaxis.set_major_locator(MaxNLocator(5))\n",
    "ax.yaxis.set_major_locator(MaxNLocator(6))\n",
    "ax.zaxis.set_major_locator(MaxNLocator(5))\n",
    "\n",
    "fig.tight_layout()\n",
    "plt.savefig('Multiplication_Function_plot.png', bbox_inches='tight')\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 133,
   "metadata": {},
   "outputs": [],
   "source": [
    "def generate_data_for_multiplication(dataset_size, upper_bound):\n",
    "    data_X = []\n",
    "    Y = []\n",
    "    for i in range(dataset_size):\n",
    "        data = np.random.uniform(-1, 1)\n",
    "        channel = np.random.uniform(upper_bound)\n",
    "        data_X.append([data, channel])\n",
    "        Y.append(data * channel)\n",
    "\n",
    "    X, Y = np.array(data_X), np.array(Y)\n",
    "    train_size = int(0.8 * dataset_size)\n",
    "    X_train, Y_train, X_test, Y_test = X[:train_size], Y[:train_size], X[train_size:], Y[train_size:]\n",
    "    return X_train, Y_train, X_test, Y_test"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 134,
   "metadata": {},
   "outputs": [],
   "source": [
    "def create_channel_multiplication_model():\n",
    "    model_inverse = Sequential()\n",
    "    model_inverse.add(Dense(2, input_shape=(2,)))\n",
    "    model_inverse.add(Dense(50, activation='sigmoid'))\n",
    "    model_inverse.add(Dense(50, activation='sigmoid'))\n",
    "    model_inverse.add(Dense(1, activation='linear'))\n",
    "    model_inverse.compile(optimizer='adam',\n",
    "                  loss='mse',\n",
    "                  metrics=['mse'])\n",
    "    return model_inverse"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 135,
   "metadata": {},
   "outputs": [],
   "source": [
    "from keras.utils import Sequence\n",
    "class MultiplicationDataGenerator(Sequence):\n",
    "\n",
    "    def __init__(self, batch_size, upper_bound):\n",
    "        self.batch_size = batch_size\n",
    "        self.x, self.y, _, _ = generate_data_for_multiplication(self.batch_size, upper_bound)\n",
    "        self.epoch = 0\n",
    "        \n",
    "    def __len__(self):\n",
    "        return int(np.ceil(len(self.x) / float(self.batch_size)))\n",
    "\n",
    "    def __getitem__(self, idx):\n",
    "        batch_x = self.x[idx * self.batch_size:(idx + 1) * self.batch_size]\n",
    "        batch_y = self.y[idx * self.batch_size:(idx + 1) * self.batch_size]\n",
    "\n",
    "        return batch_x, batch_y\n",
    "\n",
    "    def on_epoch_end(self):\n",
    "        self.x, self.y, _, _ = generate_data_for_multiplication(self.batch_size, upper_bound)\n",
    "        self.epoch += 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 136,
   "metadata": {},
   "outputs": [],
   "source": [
    "dataset_size = 50000\n",
    "train_size = int(0.8 * dataset_size)\n",
    "upper_bound = 10\n",
    "mul_X_train, mul_Y_train, mul_X_test, mul_Y_test = generate_data_for_multiplication(dataset_size, upper_bound)\n",
    "model_mul = create_channel_multiplication_model()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "batch_size = 1024\n",
    "mul_data_generator = MultiplicationDataGenerator(batch_size, upper_bound)\n",
    "history_mul = model_mul.fit_generator(mul_data_generator, steps_per_epoch=train_size // batch_size, validation_data=(mul_X_test, mul_Y_test), epochs=400)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 92,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x142a89f60>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%matplotlib inline\n",
    "plt.plot(np.log10(history_mul.history['val_loss']))\n",
    "plt.title('Neural Network Muliplication Loss vs Epoch')\n",
    "plt.ylabel('Log loss')\n",
    "plt.xlabel('epoch')\n",
    "plt.legend(['test data'], loc='upper right')\n",
    "# plt.xscale('log')\n",
    "plt.savefig('/content/gdrive/My Drive/Multiplication_loss_vs_epoch.png', bbox_inches='tight')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def run_varying_channel_upper_bound_experiment():\n",
    "    upper_bounds = [1, 5, 10, 20, 50, 100, 500]\n",
    "    errors = []\n",
    "    for channel_upper_bound in upper_bounds:\n",
    "        avg_error = []\n",
    "        print('Upper bound', channel_upper_bound)\n",
    "        for trial in range(2):\n",
    "            print('Trial', trial)\n",
    "            X_train, Y_train, X_test, Y_test = generate_data_for_multiplication(50000, channel_upper_bound)\n",
    "            batch_size = 1024\n",
    "            train_size = 10240\n",
    "            mul_data_generator = MultiplicationDataGenerator(batch_size, channel_upper_bound)\n",
    "            history_mul = model_mul.fit_generator(mul_data_generator, steps_per_epoch=train_size // batch_size, validation_data=(X_test, Y_test), epochs=100, verbose=0)\n",
    "            error = history_mul.history['val_loss'][-1]\n",
    "            print('Error', error)\n",
    "            avg_error.append(error)\n",
    "        errors.append(sum(avg_error) / 2)\n",
    "    return upper_bounds, errors"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "upper_bounds, errors = run_varying_channel_upper_bound_experiment()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# This will generate the loss vs upper bound plot\n",
    "plt.scatter(upper_bounds, np.log10(errors))\n",
    "plt.xlabel('Upper bound on channel')\n",
    "plt.ylabel('Log loss')\n",
    "plt.title('Loss of multiplication network as upper bound on channel increases')\n",
    "plt.savefig('/content/gdrive/My Drive/Channel_upper_bound_multiplication.png', bbox_inches='tight')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 95,
   "metadata": {},
   "outputs": [],
   "source": [
    "def generate_data_for_multiplication_log(dataset_size):\n",
    "    data_X = []\n",
    "    Y = []\n",
    "    for i in range(dataset_size):\n",
    "        data = np.random.uniform(0.2, 1)\n",
    "        channel = np.random.uniform(10)\n",
    "        data_X.append([data, channel])\n",
    "        Y.append(data * channel)\n",
    "\n",
    "    X, Y = np.log10(np.array(data_X)), np.log10(np.array(Y))\n",
    "    train_size = int(0.8 * dataset_size)\n",
    "    X_train, Y_train, X_test, Y_test = X[:train_size], Y[:train_size], X[train_size:], Y[train_size:]\n",
    "    return X_train, Y_train, X_test, Y_test\n",
    "\n",
    "def create_channel_multiplication_model_log():\n",
    "    model_inverse = Sequential()\n",
    "    model_inverse.add(Dense(2, input_shape=(2,)))\n",
    "    model_inverse.add(Dense(50, activation='linear'))\n",
    "    model_inverse.add(Dense(50, activation='linear'))\n",
    "    model_inverse.add(Dense(1, activation='linear'))\n",
    "    model_inverse.compile(optimizer='adam',\n",
    "                  loss='mse',\n",
    "                  metrics=['mse'])\n",
    "    return model_inverse"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 96,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train on 40000 samples, validate on 10000 samples\n",
      "Epoch 1/100\n",
      "40000/40000 [==============================] - 2s - loss: 0.0013 - mean_squared_error: 0.0013 - val_loss: 3.1528e-15 - val_mean_squared_error: 3.1528e-15\n",
      "Epoch 2/100\n",
      "40000/40000 [==============================] - 1s - loss: 3.2815e-15 - mean_squared_error: 3.2815e-15 - val_loss: 3.1452e-15 - val_mean_squared_error: 3.1452e-15\n",
      "Epoch 3/100\n",
      "40000/40000 [==============================] - 1s - loss: 3.3406e-15 - mean_squared_error: 3.3406e-15 - val_loss: 3.1004e-15 - val_mean_squared_error: 3.1004e-15\n",
      "Epoch 4/100\n",
      "40000/40000 [==============================] - 1s - loss: 3.4119e-15 - mean_squared_error: 3.4119e-15 - val_loss: 5.1045e-15 - val_mean_squared_error: 5.1045e-15\n",
      "Epoch 5/100\n",
      "40000/40000 [==============================] - 2s - loss: 4.0357e-15 - mean_squared_error: 4.0357e-15 - val_loss: 3.3508e-15 - val_mean_squared_error: 3.3508e-15\n",
      "Epoch 6/100\n",
      "40000/40000 [==============================] - 1s - loss: 4.2896e-05 - mean_squared_error: 4.2896e-05 - val_loss: 2.8090e-15 - val_mean_squared_error: 2.8090e-15\n",
      "Epoch 7/100\n",
      "40000/40000 [==============================] - 1s - loss: 2.9271e-15 - mean_squared_error: 2.9271e-15 - val_loss: 2.8479e-15 - val_mean_squared_error: 2.8479e-15\n",
      "Epoch 8/100\n",
      "40000/40000 [==============================] - 1s - loss: 3.0228e-15 - mean_squared_error: 3.0228e-15 - val_loss: 2.7996e-15 - val_mean_squared_error: 2.7996e-15\n",
      "Epoch 9/100\n",
      "40000/40000 [==============================] - 1s - loss: 4.1470e-15 - mean_squared_error: 4.1470e-15 - val_loss: 7.7194e-15 - val_mean_squared_error: 7.7194e-15\n",
      "Epoch 10/100\n",
      "40000/40000 [==============================] - 2s - loss: 3.5187e-05 - mean_squared_error: 3.5187e-05 - val_loss: 2.7948e-15 - val_mean_squared_error: 2.7948e-15\n",
      "Epoch 11/100\n",
      "40000/40000 [==============================] - 1s - loss: 2.8504e-15 - mean_squared_error: 2.8504e-15 - val_loss: 3.0305e-15 - val_mean_squared_error: 3.0305e-15\n",
      "Epoch 12/100\n",
      "40000/40000 [==============================] - 1s - loss: 3.0572e-15 - mean_squared_error: 3.0572e-15 - val_loss: 2.8014e-15 - val_mean_squared_error: 2.8014e-15\n",
      "Epoch 13/100\n",
      "40000/40000 [==============================] - 1s - loss: 4.1937e-15 - mean_squared_error: 4.1937e-15 - val_loss: 2.8560e-15 - val_mean_squared_error: 2.8560e-15\n",
      "Epoch 14/100\n",
      "40000/40000 [==============================] - 1s - loss: 2.9390e-05 - mean_squared_error: 2.9390e-05 - val_loss: 2.7212e-15 - val_mean_squared_error: 2.7212e-15\n",
      "Epoch 15/100\n",
      "40000/40000 [==============================] - 1s - loss: 2.5827e-15 - mean_squared_error: 2.5827e-15 - val_loss: 2.5318e-15 - val_mean_squared_error: 2.5318e-15\n",
      "Epoch 16/100\n",
      "40000/40000 [==============================] - 1s - loss: 2.7216e-15 - mean_squared_error: 2.7216e-15 - val_loss: 4.0140e-15 - val_mean_squared_error: 4.0140e-15\n",
      "Epoch 17/100\n",
      "40000/40000 [==============================] - 1s - loss: 3.3484e-15 - mean_squared_error: 3.3484e-15 - val_loss: 2.4824e-15 - val_mean_squared_error: 2.4824e-15\n",
      "Epoch 18/100\n",
      "40000/40000 [==============================] - 1s - loss: 4.6084e-06 - mean_squared_error: 4.6084e-06 - val_loss: 2.3800e-15 - val_mean_squared_error: 2.3800e-15\n",
      "Epoch 19/100\n",
      "40000/40000 [==============================] - 1s - loss: 3.3670e-15 - mean_squared_error: 3.3670e-15 - val_loss: 2.4129e-15 - val_mean_squared_error: 2.4129e-15\n",
      "Epoch 20/100\n",
      "40000/40000 [==============================] - 1s - loss: 2.4611e-05 - mean_squared_error: 2.4611e-05 - val_loss: 2.3906e-15 - val_mean_squared_error: 2.3906e-15\n",
      "Epoch 21/100\n",
      "40000/40000 [==============================] - 2s - loss: 2.4915e-15 - mean_squared_error: 2.4915e-15 - val_loss: 2.2861e-15 - val_mean_squared_error: 2.2861e-15\n",
      "Epoch 22/100\n",
      "40000/40000 [==============================] - 2s - loss: 2.5519e-15 - mean_squared_error: 2.5519e-15 - val_loss: 3.2074e-15 - val_mean_squared_error: 3.2074e-15\n",
      "Epoch 23/100\n",
      "40000/40000 [==============================] - 2s - loss: 4.0545e-12 - mean_squared_error: 4.0545e-12 - val_loss: 4.9866e-11 - val_mean_squared_error: 4.9866e-11\n",
      "Epoch 24/100\n",
      "40000/40000 [==============================] - 2s - loss: 3.7766e-06 - mean_squared_error: 3.7766e-06 - val_loss: 8.2657e-15 - val_mean_squared_error: 8.2657e-15\n",
      "Epoch 25/100\n",
      "40000/40000 [==============================] - 2s - loss: 4.7525e-06 - mean_squared_error: 4.7525e-06 - val_loss: 5.6773e-12 - val_mean_squared_error: 5.6773e-12\n",
      "Epoch 26/100\n",
      "40000/40000 [==============================] - 1s - loss: 5.3542e-13 - mean_squared_error: 5.3542e-13 - val_loss: 2.6552e-15 - val_mean_squared_error: 2.6552e-15\n",
      "Epoch 27/100\n",
      "40000/40000 [==============================] - 2s - loss: 7.2626e-06 - mean_squared_error: 7.2626e-06 - val_loss: 2.5140e-09 - val_mean_squared_error: 2.5140e-09\n",
      "Epoch 28/100\n",
      "40000/40000 [==============================] - 2s - loss: 3.8153e-11 - mean_squared_error: 3.8153e-11 - val_loss: 2.1840e-15 - val_mean_squared_error: 2.1840e-15\n",
      "Epoch 29/100\n",
      "40000/40000 [==============================] - 2s - loss: 7.1015e-14 - mean_squared_error: 7.1015e-14 - val_loss: 3.8445e-14 - val_mean_squared_error: 3.8445e-14\n",
      "Epoch 30/100\n",
      "40000/40000 [==============================] - 1s - loss: 2.6499e-06 - mean_squared_error: 2.6499e-06 - val_loss: 3.4177e-15 - val_mean_squared_error: 3.4177e-15\n",
      "Epoch 31/100\n",
      "40000/40000 [==============================] - 1s - loss: 2.8777e-06 - mean_squared_error: 2.8777e-06 - val_loss: 2.0536e-07 - val_mean_squared_error: 2.0536e-07\n",
      "Epoch 32/100\n",
      "40000/40000 [==============================] - 1s - loss: 7.7459e-09 - mean_squared_error: 7.7459e-09 - val_loss: 2.2227e-14 - val_mean_squared_error: 2.2227e-14\n",
      "Epoch 33/100\n",
      "40000/40000 [==============================] - 1s - loss: 1.5408e-06 - mean_squared_error: 1.5408e-06 - val_loss: 5.0045e-09 - val_mean_squared_error: 5.0045e-09\n",
      "Epoch 34/100\n",
      "40000/40000 [==============================] - 1s - loss: 1.0902e-06 - mean_squared_error: 1.0902e-06 - val_loss: 5.7732e-08 - val_mean_squared_error: 5.7732e-08\n",
      "Epoch 35/100\n",
      "40000/40000 [==============================] - 1s - loss: 1.0294e-06 - mean_squared_error: 1.0294e-06 - val_loss: 5.8502e-10 - val_mean_squared_error: 5.8502e-10\n",
      "Epoch 36/100\n",
      "40000/40000 [==============================] - 2s - loss: 2.0609e-06 - mean_squared_error: 2.0609e-06 - val_loss: 3.4078e-14 - val_mean_squared_error: 3.4078e-14\n",
      "Epoch 37/100\n",
      "40000/40000 [==============================] - 1s - loss: 1.6073e-06 - mean_squared_error: 1.6073e-06 - val_loss: 2.1586e-11 - val_mean_squared_error: 2.1586e-11\n",
      "Epoch 38/100\n",
      "40000/40000 [==============================] - 1s - loss: 3.9137e-07 - mean_squared_error: 3.9137e-07 - val_loss: 6.9234e-05 - val_mean_squared_error: 6.9234e-05\n",
      "Epoch 39/100\n",
      "40000/40000 [==============================] - 2s - loss: 2.5328e-06 - mean_squared_error: 2.5328e-06 - val_loss: 2.7335e-15 - val_mean_squared_error: 2.7335e-15\n",
      "Epoch 40/100\n",
      "40000/40000 [==============================] - 1s - loss: 5.4526e-07 - mean_squared_error: 5.4526e-07 - val_loss: 7.9166e-06 - val_mean_squared_error: 7.9166e-06\n",
      "Epoch 41/100\n",
      "40000/40000 [==============================] - 1s - loss: 1.9199e-06 - mean_squared_error: 1.9199e-06 - val_loss: 1.1189e-13 - val_mean_squared_error: 1.1189e-13\n",
      "Epoch 42/100\n",
      "40000/40000 [==============================] - 1s - loss: 1.6720e-12 - mean_squared_error: 1.6720e-12 - val_loss: 9.9775e-10 - val_mean_squared_error: 9.9775e-10\n",
      "Epoch 43/100\n",
      "40000/40000 [==============================] - 1s - loss: 1.1918e-06 - mean_squared_error: 1.1918e-06 - val_loss: 1.5963e-07 - val_mean_squared_error: 1.5963e-07\n",
      "Epoch 44/100\n",
      "40000/40000 [==============================] - 1s - loss: 1.8778e-06 - mean_squared_error: 1.8778e-06 - val_loss: 2.5410e-07 - val_mean_squared_error: 2.5410e-07\n",
      "Epoch 45/100\n",
      "40000/40000 [==============================] - 2s - loss: 5.1768e-09 - mean_squared_error: 5.1768e-09 - val_loss: 7.8826e-10 - val_mean_squared_error: 7.8826e-10\n",
      "Epoch 46/100\n",
      "40000/40000 [==============================] - 2s - loss: 1.2620e-06 - mean_squared_error: 1.2620e-06 - val_loss: 3.9271e-14 - val_mean_squared_error: 3.9271e-14\n",
      "Epoch 47/100\n",
      "40000/40000 [==============================] - 2s - loss: 9.3508e-07 - mean_squared_error: 9.3508e-07 - val_loss: 6.9089e-10 - val_mean_squared_error: 6.9089e-10\n",
      "Epoch 48/100\n",
      "40000/40000 [==============================] - 1s - loss: 6.7926e-07 - mean_squared_error: 6.7926e-07 - val_loss: 3.2404e-10 - val_mean_squared_error: 3.2404e-10\n",
      "Epoch 49/100\n",
      "40000/40000 [==============================] - 1s - loss: 9.9030e-07 - mean_squared_error: 9.9030e-07 - val_loss: 4.3476e-11 - val_mean_squared_error: 4.3476e-11\n",
      "Epoch 50/100\n",
      "40000/40000 [==============================] - 1s - loss: 1.2435e-06 - mean_squared_error: 1.2435e-06 - val_loss: 7.2189e-12 - val_mean_squared_error: 7.2189e-12\n",
      "Epoch 51/100\n",
      "40000/40000 [==============================] - 1s - loss: 1.3801e-06 - mean_squared_error: 1.3801e-06 - val_loss: 5.5920e-12 - val_mean_squared_error: 5.5920e-12\n",
      "Epoch 52/100\n",
      "40000/40000 [==============================] - 1s - loss: 3.2112e-09 - mean_squared_error: 3.2112e-09 - val_loss: 1.1459e-07 - val_mean_squared_error: 1.1459e-07\n",
      "Epoch 53/100\n",
      "40000/40000 [==============================] - 1s - loss: 1.0009e-06 - mean_squared_error: 1.0009e-06 - val_loss: 6.9647e-14 - val_mean_squared_error: 6.9647e-14\n",
      "Epoch 54/100\n",
      "40000/40000 [==============================] - 1s - loss: 1.2094e-06 - mean_squared_error: 1.2094e-06 - val_loss: 3.9719e-13 - val_mean_squared_error: 3.9719e-13\n",
      "Epoch 55/100\n",
      "40000/40000 [==============================] - 1s - loss: 7.4192e-07 - mean_squared_error: 7.4192e-07 - val_loss: 2.8660e-11 - val_mean_squared_error: 2.8660e-11\n",
      "Epoch 56/100\n",
      "40000/40000 [==============================] - 1s - loss: 5.1613e-07 - mean_squared_error: 5.1613e-07 - val_loss: 1.7476e-10 - val_mean_squared_error: 1.7476e-10\n",
      "Epoch 57/100\n",
      "40000/40000 [==============================] - 1s - loss: 9.8542e-07 - mean_squared_error: 9.8542e-07 - val_loss: 1.2865e-12 - val_mean_squared_error: 1.2865e-12\n",
      "Epoch 58/100\n",
      "40000/40000 [==============================] - 1s - loss: 7.8238e-07 - mean_squared_error: 7.8238e-07 - val_loss: 5.4957e-12 - val_mean_squared_error: 5.4957e-12\n",
      "Epoch 59/100\n",
      "40000/40000 [==============================] - 1s - loss: 5.6748e-07 - mean_squared_error: 5.6748e-07 - val_loss: 4.9075e-10 - val_mean_squared_error: 4.9075e-10\n",
      "Epoch 60/100\n",
      "40000/40000 [==============================] - 2s - loss: 1.1076e-06 - mean_squared_error: 1.1076e-06 - val_loss: 5.3337e-14 - val_mean_squared_error: 5.3337e-14\n",
      "Epoch 61/100\n",
      "40000/40000 [==============================] - 2s - loss: 7.9293e-07 - mean_squared_error: 7.9293e-07 - val_loss: 1.4077e-07 - val_mean_squared_error: 1.4077e-07\n",
      "Epoch 62/100\n",
      "40000/40000 [==============================] - 1s - loss: 3.3072e-06 - mean_squared_error: 3.3072e-06 - val_loss: 1.6433e-08 - val_mean_squared_error: 1.6433e-08\n",
      "Epoch 63/100\n",
      "40000/40000 [==============================] - 2s - loss: 5.4535e-10 - mean_squared_error: 5.4535e-10 - val_loss: 6.6442e-15 - val_mean_squared_error: 6.6442e-15\n",
      "Epoch 64/100\n",
      "40000/40000 [==============================] - 2s - loss: 7.3216e-14 - mean_squared_error: 7.3216e-14 - val_loss: 1.7621e-13 - val_mean_squared_error: 1.7621e-13\n",
      "Epoch 65/100\n",
      "40000/40000 [==============================] - 2s - loss: 7.8745e-07 - mean_squared_error: 7.8745e-07 - val_loss: 4.7502e-08 - val_mean_squared_error: 4.7502e-08\n",
      "Epoch 66/100\n",
      "40000/40000 [==============================] - 1s - loss: 1.9558e-07 - mean_squared_error: 1.9558e-07 - val_loss: 3.3129e-11 - val_mean_squared_error: 3.3129e-11\n",
      "Epoch 67/100\n",
      "40000/40000 [==============================] - 2s - loss: 2.2132e-06 - mean_squared_error: 2.2132e-06 - val_loss: 2.1621e-15 - val_mean_squared_error: 2.1621e-15\n",
      "Epoch 68/100\n",
      "40000/40000 [==============================] - 1s - loss: 2.6914e-15 - mean_squared_error: 2.6914e-15 - val_loss: 2.2638e-15 - val_mean_squared_error: 2.2638e-15\n",
      "Epoch 69/100\n",
      "40000/40000 [==============================] - 1s - loss: 6.4202e-07 - mean_squared_error: 6.4202e-07 - val_loss: 4.6576e-13 - val_mean_squared_error: 4.6576e-13\n",
      "Epoch 70/100\n",
      "40000/40000 [==============================] - 2s - loss: 9.8818e-07 - mean_squared_error: 9.8818e-07 - val_loss: 1.3137e-14 - val_mean_squared_error: 1.3137e-14\n",
      "Epoch 71/100\n",
      "40000/40000 [==============================] - 2s - loss: 1.3002e-06 - mean_squared_error: 1.3002e-06 - val_loss: 3.0556e-07 - val_mean_squared_error: 3.0556e-07\n",
      "Epoch 72/100\n",
      "40000/40000 [==============================] - 2s - loss: 4.2445e-07 - mean_squared_error: 4.2445e-07 - val_loss: 2.4685e-15 - val_mean_squared_error: 2.4685e-15\n",
      "Epoch 73/100\n",
      "40000/40000 [==============================] - 1s - loss: 7.1686e-09 - mean_squared_error: 7.1686e-09 - val_loss: 4.8718e-07 - val_mean_squared_error: 4.8718e-07\n",
      "Epoch 74/100\n",
      "40000/40000 [==============================] - 1s - loss: 1.1051e-06 - mean_squared_error: 1.1051e-06 - val_loss: 2.9949e-15 - val_mean_squared_error: 2.9949e-15\n",
      "Epoch 75/100\n",
      "40000/40000 [==============================] - 1s - loss: 5.9898e-07 - mean_squared_error: 5.9898e-07 - val_loss: 2.1866e-11 - val_mean_squared_error: 2.1866e-11\n",
      "Epoch 76/100\n",
      "40000/40000 [==============================] - 1s - loss: 1.8934e-06 - mean_squared_error: 1.8934e-06 - val_loss: 8.4046e-11 - val_mean_squared_error: 8.4046e-11\n",
      "Epoch 77/100\n",
      "40000/40000 [==============================] - 1s - loss: 2.0639e-12 - mean_squared_error: 2.0639e-12 - val_loss: 2.4664e-15 - val_mean_squared_error: 2.4664e-15\n",
      "Epoch 78/100\n",
      "40000/40000 [==============================] - 1s - loss: 2.6660e-12 - mean_squared_error: 2.6660e-12 - val_loss: 6.6941e-12 - val_mean_squared_error: 6.6941e-12\n",
      "Epoch 79/100\n",
      "40000/40000 [==============================] - 1s - loss: 1.0839e-06 - mean_squared_error: 1.0839e-06 - val_loss: 8.7438e-14 - val_mean_squared_error: 8.7438e-14\n",
      "Epoch 80/100\n",
      "40000/40000 [==============================] - 1s - loss: 3.1155e-07 - mean_squared_error: 3.1155e-07 - val_loss: 1.2828e-08 - val_mean_squared_error: 1.2828e-08\n",
      "Epoch 81/100\n",
      "40000/40000 [==============================] - 1s - loss: 3.2428e-07 - mean_squared_error: 3.2428e-07 - val_loss: 1.5778e-13 - val_mean_squared_error: 1.5778e-13\n",
      "Epoch 82/100\n",
      "40000/40000 [==============================] - 1s - loss: 4.8304e-07 - mean_squared_error: 4.8304e-07 - val_loss: 6.9496e-07 - val_mean_squared_error: 6.9496e-07\n",
      "Epoch 83/100\n",
      "40000/40000 [==============================] - 1s - loss: 5.6425e-07 - mean_squared_error: 5.6425e-07 - val_loss: 1.0269e-10 - val_mean_squared_error: 1.0269e-10\n",
      "Epoch 84/100\n",
      "40000/40000 [==============================] - 1s - loss: 5.8650e-07 - mean_squared_error: 5.8650e-07 - val_loss: 9.7425e-15 - val_mean_squared_error: 9.7425e-15\n",
      "Epoch 85/100\n",
      "40000/40000 [==============================] - 2s - loss: 6.6696e-07 - mean_squared_error: 6.6696e-07 - val_loss: 2.8433e-14 - val_mean_squared_error: 2.8433e-14\n",
      "Epoch 86/100\n",
      "40000/40000 [==============================] - 2s - loss: 5.8834e-07 - mean_squared_error: 5.8834e-07 - val_loss: 8.4664e-07 - val_mean_squared_error: 8.4664e-07\n",
      "Epoch 87/100\n",
      "40000/40000 [==============================] - 1s - loss: 6.1721e-07 - mean_squared_error: 6.1721e-07 - val_loss: 7.4380e-06 - val_mean_squared_error: 7.4380e-06\n",
      "Epoch 88/100\n",
      "40000/40000 [==============================] - 2s - loss: 1.2445e-07 - mean_squared_error: 1.2445e-07 - val_loss: 3.9325e-15 - val_mean_squared_error: 3.9325e-15\n",
      "Epoch 89/100\n",
      "40000/40000 [==============================] - 1s - loss: 1.1309e-06 - mean_squared_error: 1.1309e-06 - val_loss: 2.1943e-14 - val_mean_squared_error: 2.1943e-14\n",
      "Epoch 90/100\n",
      "40000/40000 [==============================] - 2s - loss: 1.2058e-14 - mean_squared_error: 1.2058e-14 - val_loss: 3.0393e-15 - val_mean_squared_error: 3.0393e-15\n",
      "Epoch 91/100\n",
      "40000/40000 [==============================] - 2s - loss: 4.9964e-07 - mean_squared_error: 4.9964e-07 - val_loss: 4.0832e-14 - val_mean_squared_error: 4.0832e-14\n",
      "Epoch 92/100\n",
      "40000/40000 [==============================] - 2s - loss: 4.5624e-07 - mean_squared_error: 4.5624e-07 - val_loss: 2.6011e-13 - val_mean_squared_error: 2.6011e-13\n",
      "Epoch 93/100\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "40000/40000 [==============================] - 2s - loss: 9.1855e-07 - mean_squared_error: 9.1855e-07 - val_loss: 2.3485e-15 - val_mean_squared_error: 2.3485e-15\n",
      "Epoch 94/100\n",
      "40000/40000 [==============================] - 2s - loss: 2.5537e-09 - mean_squared_error: 2.5537e-09 - val_loss: 4.7039e-07 - val_mean_squared_error: 4.7039e-07\n",
      "Epoch 95/100\n",
      "40000/40000 [==============================] - 2s - loss: 6.2186e-07 - mean_squared_error: 6.2186e-07 - val_loss: 1.5186e-12 - val_mean_squared_error: 1.5186e-12\n",
      "Epoch 96/100\n",
      "40000/40000 [==============================] - 1s - loss: 4.8432e-07 - mean_squared_error: 4.8432e-07 - val_loss: 1.4900e-13 - val_mean_squared_error: 1.4900e-13\n",
      "Epoch 97/100\n",
      "40000/40000 [==============================] - 1s - loss: 2.5483e-07 - mean_squared_error: 2.5483e-07 - val_loss: 1.7054e-11 - val_mean_squared_error: 1.7054e-11\n",
      "Epoch 98/100\n",
      "40000/40000 [==============================] - 2s - loss: 1.3202e-06 - mean_squared_error: 1.3202e-06 - val_loss: 1.9216e-15 - val_mean_squared_error: 1.9216e-15\n",
      "Epoch 99/100\n",
      "40000/40000 [==============================] - 1s - loss: 6.6611e-15 - mean_squared_error: 6.6611e-15 - val_loss: 2.2883e-15 - val_mean_squared_error: 2.2883e-15\n",
      "Epoch 100/100\n",
      "40000/40000 [==============================] - 1s - loss: 2.6511e-07 - mean_squared_error: 2.6511e-07 - val_loss: 1.5173e-06 - val_mean_squared_error: 1.5173e-06\n"
     ]
    }
   ],
   "source": [
    "dataset_size = 50000\n",
    "mul_X_train_log, mul_Y_train_log, mul_X_test_log, mul_Y_test_log = generate_data_for_multiplication_log(dataset_size)\n",
    "model_mul = create_channel_multiplication_model_log()\n",
    "history_log = model_mul.fit(mul_X_train_log, mul_Y_train_log, validation_data=(mul_X_test_log, mul_Y_test_log), epochs=100, batch_size=64)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 97,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x14372e780>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%matplotlib inline\n",
    "plt.plot(np.log10(history_log.history['loss']))\n",
    "plt.plot(np.log10(history_log.history['val_loss']))\n",
    "plt.title('Multiplication loss log features (deeper LSTM with no channel preprocessing)')\n",
    "plt.ylabel('loss')\n",
    "plt.xlabel('epoch')\n",
    "plt.legend(['train', 'test'], loc='upper left')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Equalization"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np \n",
    "from keras.models import Sequential\n",
    "from keras.layers import Dense\n",
    "from keras.layers import LSTM\n",
    "import scipy.signal as sig\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "from sklearn.model_selection import train_test_split\n",
    "from keras.layers import Input\n",
    "from keras.layers import concatenate\n",
    "from keras.models import Model\n",
    "from keras.utils import plot_model\n",
    "from IPython.display import SVG\n",
    "from keras.utils.vis_utils import model_to_dot\n",
    "from keras.layers import TimeDistributed\n",
    "from keras.layers import Bidirectional\n",
    "from keras.layers import RepeatVector"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "def qam_4_modulation(bitstring):\n",
    "    modulated_symbol = []\n",
    "    reshaped_bit_string = bitstring.reshape((len(bitstring) // 2 , 2))\n",
    "\n",
    "    for row in reshaped_bit_string:\n",
    "        if np.array_equal(row, np.array([0, 0])):\n",
    "            modulated_symbol.append(1 + 1j)\n",
    "        elif np.array_equal(row, np.array([1, 0])):\n",
    "            modulated_symbol.append(-1 + 1j)\n",
    "        elif np.array_equal(row, np.array([1, 1])):\n",
    "            modulated_symbol.append(-1 - 1j)\n",
    "        else:\n",
    "            modulated_symbol.append(1 - 1j)\n",
    "    return np.array(modulated_symbol)\n",
    "\n",
    "def add_awgn_noise(signal,SNR_dB):\n",
    "    \"\"\"  Adds AWGN noise vector to signal \n",
    "         to generate a resulting signal vector y of specified SNR in dB\n",
    "    \"\"\"\n",
    "    L=len(signal)\n",
    "    SNR = 10**(SNR_dB/20.0) #SNR to linear scale\n",
    "    Esym=np.sum(np.square(np.abs(signal)))/L #Calculate actual symbol energy\n",
    "    N0=Esym/SNR; #Find the noise spectral density\n",
    "    if(isinstance(signal[0], complex)):\n",
    "        noiseSigma=np.sqrt(N0/2.0)#Standard deviation for AWGN Noise when x is complex\n",
    "        n = noiseSigma*(np.random.randn(1,L)+1j*np.random.randn(1,L))#computed noise \n",
    "    else:\n",
    "        noiseSigma = np.sqrt(N0);#Standard deviation for AWGN Noise when x is real\n",
    "        n = noiseSigma*np.random.randn(1,L)#computed noise\n",
    "    y = signal + n #received signal\n",
    "    \n",
    "    return y.flatten()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [],
   "source": [
    "def generate_combined_dataset_qam_4_edited(dataset_size,  preamble_length, data_length, channel_length, SNR, constellations):\n",
    "#     QAMModem = cp.modulation.QAMModem(constellations)\n",
    "    \n",
    "    # use the constellation object to modulate the data bits into complex numbers\n",
    "    \n",
    "    \n",
    "    preambles_constellations = []\n",
    "    input_data_constellations = []\n",
    "    convolved_preambles = []\n",
    "    convolved_data_constellations = []\n",
    "    channels = []\n",
    "    \n",
    "    for i in range(dataset_size):\n",
    "        input_data_bits = np.random.randint(0, 2, data_length)\n",
    "        preambles = np.random.randint(0, 2, preamble_length)\n",
    "        \n",
    "        input_data_constellation = qam_4_modulation(input_data_bits)\n",
    "        real_input = np.real(input_data_constellation)\n",
    "        im_input = np.imag(input_data_constellation)\n",
    "        real_im_input = np.vstack((real_input,im_input)).T\n",
    "        input_data_constellations.append(real_im_input)\n",
    "        \n",
    "        preambles_constellation =  qam_4_modulation(preambles)\n",
    "        real_preambles = np.real(preambles_constellation)\n",
    "        im_preambles = np.imag(preambles_constellation)\n",
    "        real_im_preambles = np.vstack((real_preambles,im_preambles)).reshape((-1,),order='F')\n",
    "        preambles_constellations.append(real_im_preambles)\n",
    "        channel_taps = [0, 0]\n",
    "        channel_taps[0] = np.random.uniform(-1, 1)\n",
    "        channel_taps[1] = np.random.uniform(-1, 1)\n",
    "        channel_taps = channel_taps / np.linalg.norm(channel_taps)\n",
    "        channels.append(channel_taps)\n",
    "        \n",
    "        preamble_conv = sig.convolve(preambles_constellation, channel_taps, mode='same')\n",
    "        real_preambles_conv = np.real(preamble_conv)\n",
    "        im_preambles_conv = np.imag(preamble_conv)\n",
    "        real_im_preambles_conv = np.vstack((real_preambles_conv,im_preambles_conv)).reshape((-1,),order='F')\n",
    "        convolved_preambles.append(real_im_preambles_conv)\n",
    "        \n",
    "        constellation_convolved = add_awgn_noise(sig.convolve(input_data_constellation, channel_taps, mode='same'), SNR)\n",
    "        real_constellation_conv = np.real(constellation_convolved)\n",
    "        im_constellation_conv = np.imag(constellation_convolved)\n",
    "        real_im_constellation_conv = np.vstack((real_constellation_conv,im_constellation_conv)).T\n",
    "        convolved_data_constellations.append(real_im_constellation_conv)\n",
    "        \n",
    "    X1 = np.hstack([preambles_constellations, np.array(convolved_preambles)])\n",
    "    X2 = np.array(convolved_data_constellations)\n",
    "    Y = np.array(input_data_constellations)\n",
    "    channels = np.array(channels)\n",
    "#     plt.scatter(np.zeros(input_data_constellations.shape[1]), input_data_constellations[0])\n",
    "#     plt.show()\n",
    "    return X1, X2, Y, channels"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [],
   "source": [
    "def transform_data(channel_data, convolved_data, input_data_symbols, sequence_length, window_length=3):\n",
    "    channels, convolved_data_features, input_data_symbols_target = [], [], []\n",
    "    for i in range(convolved_data.shape[0]):\n",
    "        data_sequence, input_symbols = convolved_data[i], input_data_symbols[i]\n",
    "        channel = channel_data[i]\n",
    "        for j in range(sequence_length - window_length + 1):\n",
    "            convolved_data_features.append(data_sequence[j:j+window_length])\n",
    "            input_data_symbols_target.append(input_symbols[j:j+window_length])\n",
    "            channels.append(channel)\n",
    "    #       print(i, j)\n",
    "          \n",
    "    return np.array(channels), np.array(convolved_data_features), np.array(input_data_symbols_target)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 96,
   "metadata": {},
   "outputs": [],
   "source": [
    "def generate_training_data_equalization(dataset_size, preamble_length, data_length, channel_length, SNR, constellations, window_length):\n",
    "    preamble_data, convolved_data, input_data_symbols, channels = generate_combined_dataset_qam_4_edited(dataset_size, preamble_length, data_length, channel_length, SNR, constellations)\n",
    "    channels, convolved_data, input_data_symbols = transform_data(channels, convolved_data, input_data_symbols, data_length // 2, window_length)\n",
    "    \n",
    "    preamble_train, preamble_test = preamble_data[:train_size], preamble_data[train_size:]\n",
    "    convolved_train, convolved_test = convolved_data[:train_size], convolved_data[train_size:]\n",
    "    input_data_symbols_train, input_data_symbols_test = input_data_symbols[:train_size], input_data_symbols[train_size:]\n",
    "    channel_train, channel_test = channels[:train_size], channels[train_size:]\n",
    "    return [channel_train, convolved_train], input_data_symbols_train\n",
    "\n",
    "from keras.utils import Sequence\n",
    "\n",
    "class DataGenerator(Sequence):\n",
    "\n",
    "    def __init__(self, dataset_size, preamble_length, data_length, channel_length, \n",
    "                 SNR, constellations, window_length, batch_size):\n",
    "        self.x, self.y = generate_training_data_equalization(dataset_size, preamble_length, data_length, channel_length, \n",
    "                 SNR, constellations, window_length)\n",
    "        self.epoch = 0\n",
    "        self.batch_size = batch_size\n",
    "        self.dataset_size = dataset_size\n",
    "        self.preamble_length = preamble_length\n",
    "        self.data_length = data_length\n",
    "        self.channel_length = channel_length\n",
    "        self.SNR = SNR\n",
    "        self.constellations = constellations\n",
    "        self.window_length = window_length\n",
    "\n",
    "    def __len__(self):\n",
    "        return int(np.ceil(len(self.x) / float(self.batch_size)))\n",
    "\n",
    "    def __getitem__(self, idx):\n",
    "        batch_x = [self.x[0][idx * self.batch_size:(idx + 1) * self.batch_size], \n",
    "                   self.x[1][idx * self.batch_size:(idx + 1) * self.batch_size]]\n",
    "        batch_y = self.y[idx * self.batch_size:(idx + 1) * self.batch_size]\n",
    "#         print(batch_x)\n",
    "#         print(batch_y)\n",
    "        return batch_x, batch_y\n",
    "\n",
    "    def on_epoch_end(self):\n",
    "#         print('Generating data')\n",
    "        self.x, self.y = generate_training_data_equalization(self.batch_size, self.preamble_length, self.data_length, \n",
    "                                                             self.channel_length, self.SNR, self.constellations, self.window_length)\n",
    "            # modify data\n",
    "        self.epoch += 1\n",
    "        \n",
    "        \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 109,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(840000, 10, 2) (210000, 10, 2)\n",
      "(840000, 10, 2) (210000, 10, 2)\n",
      "(840000, 2) (210000, 2)\n"
     ]
    }
   ],
   "source": [
    "preamble_length = 80\n",
    "data_length = 60\n",
    "dataset_size = 50000\n",
    "channel_length = 2\n",
    "SNR = 100\n",
    "constellations = 4\n",
    "window_length = 10\n",
    "batch_size = 1024\n",
    "preamble_data, convolved_data, input_data_symbols, channels = generate_combined_dataset_qam_4_edited(dataset_size, preamble_length, data_length, channel_length, SNR, constellations)\n",
    "channels, convolved_data, input_data_symbols = transform_data(channels, convolved_data, input_data_symbols, data_length // 2, window_length=window_length)\n",
    "train_size = int(input_data_symbols.shape[0] * 0.8)\n",
    "preamble_train, preamble_test = preamble_data[:train_size], preamble_data[train_size:]\n",
    "convolved_train, convolved_test = convolved_data[:train_size], convolved_data[train_size:]\n",
    "input_data_symbols_train, input_data_symbols_test = input_data_symbols[:train_size], input_data_symbols[train_size:]\n",
    "channel_train, channel_test = channels[:train_size], channels[train_size:]\n",
    "# print(preamble_train.shape, preamble_test.shape)\n",
    "print(convolved_train.shape, convolved_test.shape)\n",
    "print(input_data_symbols_train.shape, input_data_symbols_test.shape)\n",
    "print(channel_train.shape, channel_test.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 98,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<__main__.DataGenerator at 0x1c77306a0>"
      ]
     },
     "execution_count": 98,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data_generator = DataGenerator(dataset_size, preamble_length, data_length, channel_length, \n",
    "                 SNR, constellations, window_length, batch_size)\n",
    "data_generator"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 99,
   "metadata": {},
   "outputs": [],
   "source": [
    "def build_end_to_end_model_two_tap_channel_deeper_LSTM_no_preprocessing(preamble_length, data_length, channel_length, output_length):\n",
    "    \n",
    "    channel = Input(shape=(channel_length,))\n",
    "    data = Input(shape=(data_length, 2))\n",
    "    channel_repeated = RepeatVector(data_length)(channel)\n",
    "\n",
    "    output = concatenate([data, channel_repeated])\n",
    "    data_layers = Bidirectional(LSTM(90, return_sequences=True))(output)\n",
    "    data_layers_2 = Bidirectional(LSTM(90, return_sequences=True))(data_layers)\n",
    "    data_layers_3 = Bidirectional(LSTM(90, return_sequences=True))(data_layers_2)\n",
    "    data_layers_4 = Bidirectional(LSTM(90, return_sequences=True))(data_layers_3)\n",
    "\n",
    "    output_1 = TimeDistributed(Dense(100, activation='relu'))(data_layers_4)\n",
    "    output_2 = TimeDistributed(Dense(100, activation='relu'))(output_1)\n",
    "    output = TimeDistributed(Dense(2, activation='linear'))(output_1)\n",
    "    model = Model(inputs=[channel, data], outputs=[output])\n",
    "\n",
    "    model.compile(optimizer='adagrad', loss='mse', metrics=['mse'])\n",
    "    return model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 100,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<svg height=\"701pt\" viewBox=\"0.00 0.00 649.98 701.00\" width=\"650pt\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g class=\"graph\" id=\"graph0\" transform=\"scale(1 1) rotate(0) translate(4 697)\">\n",
       "<title>G</title>\n",
       "<polygon fill=\"#ffffff\" points=\"-4,4 -4,-697 645.9834,-697 645.9834,4 -4,4\" stroke=\"transparent\"/>\n",
       "<!-- 7641185696 -->\n",
       "<g class=\"node\" id=\"node1\">\n",
       "<title>7641185696</title>\n",
       "<polygon fill=\"none\" points=\"40.8037,-648.5 40.8037,-692.5 301.4834,-692.5 301.4834,-648.5 40.8037,-648.5\" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"108.4849\" y=\"-666.3\">input_27: InputLayer</text>\n",
       "<polyline fill=\"none\" points=\"176.166,-648.5 176.166,-692.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"204.0005\" y=\"-677.3\">input:</text>\n",
       "<polyline fill=\"none\" points=\"176.166,-670.5 231.835,-670.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"204.0005\" y=\"-655.3\">output:</text>\n",
       "<polyline fill=\"none\" points=\"231.835,-648.5 231.835,-692.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"266.6592\" y=\"-677.3\">(None, 2)</text>\n",
       "<polyline fill=\"none\" points=\"231.835,-670.5 301.4834,-670.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"266.6592\" y=\"-655.3\">(None, 2)</text>\n",
       "</g>\n",
       "<!-- 7641165440 -->\n",
       "<g class=\"node\" id=\"node3\">\n",
       "<title>7641165440</title>\n",
       "<polygon fill=\"none\" points=\"0,-567.5 0,-611.5 342.2871,-611.5 342.2871,-567.5 0,-567.5\" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"97.9849\" y=\"-585.3\">repeat_vector_14: RepeatVector</text>\n",
       "<polyline fill=\"none\" points=\"195.9697,-567.5 195.9697,-611.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"223.8042\" y=\"-596.3\">input:</text>\n",
       "<polyline fill=\"none\" points=\"195.9697,-589.5 251.6387,-589.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"223.8042\" y=\"-574.3\">output:</text>\n",
       "<polyline fill=\"none\" points=\"251.6387,-567.5 251.6387,-611.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"296.9629\" y=\"-596.3\">(None, 2)</text>\n",
       "<polyline fill=\"none\" points=\"251.6387,-589.5 342.2871,-589.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"296.9629\" y=\"-574.3\">(None, 10, 2)</text>\n",
       "</g>\n",
       "<!-- 7641185696&#45;&gt;7641165440 -->\n",
       "<g class=\"edge\" id=\"edge1\">\n",
       "<title>7641185696-&gt;7641165440</title>\n",
       "<path d=\"M171.1436,-648.3664C171.1436,-640.1516 171.1436,-630.6579 171.1436,-621.7252\" fill=\"none\" stroke=\"#000000\"/>\n",
       "<polygon fill=\"#000000\" points=\"174.6437,-621.6068 171.1436,-611.6068 167.6437,-621.6069 174.6437,-621.6068\" stroke=\"#000000\"/>\n",
       "</g>\n",
       "<!-- 7641185472 -->\n",
       "<g class=\"node\" id=\"node2\">\n",
       "<title>7641185472</title>\n",
       "<polygon fill=\"none\" points=\"360.3037,-567.5 360.3037,-611.5 641.9834,-611.5 641.9834,-567.5 360.3037,-567.5\" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"427.9849\" y=\"-585.3\">input_28: InputLayer</text>\n",
       "<polyline fill=\"none\" points=\"495.666,-567.5 495.666,-611.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"523.5005\" y=\"-596.3\">input:</text>\n",
       "<polyline fill=\"none\" points=\"495.666,-589.5 551.335,-589.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"523.5005\" y=\"-574.3\">output:</text>\n",
       "<polyline fill=\"none\" points=\"551.335,-567.5 551.335,-611.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"596.6592\" y=\"-596.3\">(None, 10, 2)</text>\n",
       "<polyline fill=\"none\" points=\"551.335,-589.5 641.9834,-589.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"596.6592\" y=\"-574.3\">(None, 10, 2)</text>\n",
       "</g>\n",
       "<!-- 7641165216 -->\n",
       "<g class=\"node\" id=\"node4\">\n",
       "<title>7641165216</title>\n",
       "<polygon fill=\"none\" points=\"127.6792,-486.5 127.6792,-530.5 544.6079,-530.5 544.6079,-486.5 127.6792,-486.5\" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"217.4985\" y=\"-504.3\">concatenate_14: Concatenate</text>\n",
       "<polyline fill=\"none\" points=\"307.3179,-486.5 307.3179,-530.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"335.1523\" y=\"-515.3\">input:</text>\n",
       "<polyline fill=\"none\" points=\"307.3179,-508.5 362.9868,-508.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"335.1523\" y=\"-493.3\">output:</text>\n",
       "<polyline fill=\"none\" points=\"362.9868,-486.5 362.9868,-530.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"453.7974\" y=\"-515.3\">[(None, 10, 2), (None, 10, 2)]</text>\n",
       "<polyline fill=\"none\" points=\"362.9868,-508.5 544.6079,-508.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"453.311\" y=\"-493.3\">(None, 10, 4)</text>\n",
       "</g>\n",
       "<!-- 7641185472&#45;&gt;7641165216 -->\n",
       "<g class=\"edge\" id=\"edge2\">\n",
       "<title>7641185472-&gt;7641165216</title>\n",
       "<path d=\"M456.0566,-567.3664C435.776,-557.4105 411.6686,-545.5759 390.4066,-535.1382\" fill=\"none\" stroke=\"#000000\"/>\n",
       "<polygon fill=\"#000000\" points=\"391.6951,-531.8718 381.176,-530.6068 388.6103,-538.1555 391.6951,-531.8718\" stroke=\"#000000\"/>\n",
       "</g>\n",
       "<!-- 7641165440&#45;&gt;7641165216 -->\n",
       "<g class=\"edge\" id=\"edge3\">\n",
       "<title>7641165440-&gt;7641165216</title>\n",
       "<path d=\"M216.2305,-567.3664C236.5111,-557.4105 260.6185,-545.5759 281.8805,-535.1382\" fill=\"none\" stroke=\"#000000\"/>\n",
       "<polygon fill=\"#000000\" points=\"283.6768,-538.1555 291.1111,-530.6068 280.592,-531.8718 283.6768,-538.1555\" stroke=\"#000000\"/>\n",
       "</g>\n",
       "<!-- 7641165496 -->\n",
       "<g class=\"node\" id=\"node5\">\n",
       "<title>7641165496</title>\n",
       "<polygon fill=\"none\" points=\"111.3174,-405.5 111.3174,-449.5 560.9697,-449.5 560.9697,-405.5 111.3174,-405.5\" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"255.9849\" y=\"-423.3\">bidirectional_53(lstm_53): Bidirectional(LSTM)</text>\n",
       "<polyline fill=\"none\" points=\"400.6523,-405.5 400.6523,-449.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"428.4868\" y=\"-434.3\">input:</text>\n",
       "<polyline fill=\"none\" points=\"400.6523,-427.5 456.3213,-427.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"428.4868\" y=\"-412.3\">output:</text>\n",
       "<polyline fill=\"none\" points=\"456.3213,-405.5 456.3213,-449.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"508.6455\" y=\"-434.3\">(None, 10, 4)</text>\n",
       "<polyline fill=\"none\" points=\"456.3213,-427.5 560.9697,-427.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"508.6455\" y=\"-412.3\">(None, 10, 180)</text>\n",
       "</g>\n",
       "<!-- 7641165216&#45;&gt;7641165496 -->\n",
       "<g class=\"edge\" id=\"edge4\">\n",
       "<title>7641165216-&gt;7641165496</title>\n",
       "<path d=\"M336.1436,-486.3664C336.1436,-478.1516 336.1436,-468.6579 336.1436,-459.7252\" fill=\"none\" stroke=\"#000000\"/>\n",
       "<polygon fill=\"#000000\" points=\"339.6437,-459.6068 336.1436,-449.6068 332.6437,-459.6069 339.6437,-459.6068\" stroke=\"#000000\"/>\n",
       "</g>\n",
       "<!-- 7441104232 -->\n",
       "<g class=\"node\" id=\"node6\">\n",
       "<title>7441104232</title>\n",
       "<polygon fill=\"none\" points=\"111.3174,-324.5 111.3174,-368.5 560.9697,-368.5 560.9697,-324.5 111.3174,-324.5\" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"255.9849\" y=\"-342.3\">bidirectional_54(lstm_54): Bidirectional(LSTM)</text>\n",
       "<polyline fill=\"none\" points=\"400.6523,-324.5 400.6523,-368.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"428.4868\" y=\"-353.3\">input:</text>\n",
       "<polyline fill=\"none\" points=\"400.6523,-346.5 456.3213,-346.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"428.4868\" y=\"-331.3\">output:</text>\n",
       "<polyline fill=\"none\" points=\"456.3213,-324.5 456.3213,-368.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"508.6455\" y=\"-353.3\">(None, 10, 180)</text>\n",
       "<polyline fill=\"none\" points=\"456.3213,-346.5 560.9697,-346.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"508.6455\" y=\"-331.3\">(None, 10, 180)</text>\n",
       "</g>\n",
       "<!-- 7641165496&#45;&gt;7441104232 -->\n",
       "<g class=\"edge\" id=\"edge5\">\n",
       "<title>7641165496-&gt;7441104232</title>\n",
       "<path d=\"M336.1436,-405.3664C336.1436,-397.1516 336.1436,-387.6579 336.1436,-378.7252\" fill=\"none\" stroke=\"#000000\"/>\n",
       "<polygon fill=\"#000000\" points=\"339.6437,-378.6068 336.1436,-368.6068 332.6437,-378.6069 339.6437,-378.6068\" stroke=\"#000000\"/>\n",
       "</g>\n",
       "<!-- 8128236400 -->\n",
       "<g class=\"node\" id=\"node7\">\n",
       "<title>8128236400</title>\n",
       "<polygon fill=\"none\" points=\"111.3174,-243.5 111.3174,-287.5 560.9697,-287.5 560.9697,-243.5 111.3174,-243.5\" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"255.9849\" y=\"-261.3\">bidirectional_55(lstm_55): Bidirectional(LSTM)</text>\n",
       "<polyline fill=\"none\" points=\"400.6523,-243.5 400.6523,-287.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"428.4868\" y=\"-272.3\">input:</text>\n",
       "<polyline fill=\"none\" points=\"400.6523,-265.5 456.3213,-265.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"428.4868\" y=\"-250.3\">output:</text>\n",
       "<polyline fill=\"none\" points=\"456.3213,-243.5 456.3213,-287.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"508.6455\" y=\"-272.3\">(None, 10, 180)</text>\n",
       "<polyline fill=\"none\" points=\"456.3213,-265.5 560.9697,-265.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"508.6455\" y=\"-250.3\">(None, 10, 180)</text>\n",
       "</g>\n",
       "<!-- 7441104232&#45;&gt;8128236400 -->\n",
       "<g class=\"edge\" id=\"edge6\">\n",
       "<title>7441104232-&gt;8128236400</title>\n",
       "<path d=\"M336.1436,-324.3664C336.1436,-316.1516 336.1436,-306.6579 336.1436,-297.7252\" fill=\"none\" stroke=\"#000000\"/>\n",
       "<polygon fill=\"#000000\" points=\"339.6437,-297.6068 336.1436,-287.6068 332.6437,-297.6069 339.6437,-297.6068\" stroke=\"#000000\"/>\n",
       "</g>\n",
       "<!-- 8142044968 -->\n",
       "<g class=\"node\" id=\"node8\">\n",
       "<title>8142044968</title>\n",
       "<polygon fill=\"none\" points=\"111.3174,-162.5 111.3174,-206.5 560.9697,-206.5 560.9697,-162.5 111.3174,-162.5\" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"255.9849\" y=\"-180.3\">bidirectional_56(lstm_56): Bidirectional(LSTM)</text>\n",
       "<polyline fill=\"none\" points=\"400.6523,-162.5 400.6523,-206.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"428.4868\" y=\"-191.3\">input:</text>\n",
       "<polyline fill=\"none\" points=\"400.6523,-184.5 456.3213,-184.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"428.4868\" y=\"-169.3\">output:</text>\n",
       "<polyline fill=\"none\" points=\"456.3213,-162.5 456.3213,-206.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"508.6455\" y=\"-191.3\">(None, 10, 180)</text>\n",
       "<polyline fill=\"none\" points=\"456.3213,-184.5 560.9697,-184.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"508.6455\" y=\"-169.3\">(None, 10, 180)</text>\n",
       "</g>\n",
       "<!-- 8128236400&#45;&gt;8142044968 -->\n",
       "<g class=\"edge\" id=\"edge7\">\n",
       "<title>8128236400-&gt;8142044968</title>\n",
       "<path d=\"M336.1436,-243.3664C336.1436,-235.1516 336.1436,-225.6579 336.1436,-216.7252\" fill=\"none\" stroke=\"#000000\"/>\n",
       "<polygon fill=\"#000000\" points=\"339.6437,-216.6068 336.1436,-206.6068 332.6437,-216.6069 339.6437,-216.6068\" stroke=\"#000000\"/>\n",
       "</g>\n",
       "<!-- 8153512592 -->\n",
       "<g class=\"node\" id=\"node9\">\n",
       "<title>8153512592</title>\n",
       "<polygon fill=\"none\" points=\"88.7485,-81.5 88.7485,-125.5 583.5386,-125.5 583.5386,-81.5 88.7485,-81.5\" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"255.9849\" y=\"-99.3\">time_distributed_40(dense_40): TimeDistributed(Dense)</text>\n",
       "<polyline fill=\"none\" points=\"423.2212,-81.5 423.2212,-125.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"451.0557\" y=\"-110.3\">input:</text>\n",
       "<polyline fill=\"none\" points=\"423.2212,-103.5 478.8901,-103.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"451.0557\" y=\"-88.3\">output:</text>\n",
       "<polyline fill=\"none\" points=\"478.8901,-81.5 478.8901,-125.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"531.2144\" y=\"-110.3\">(None, 10, 180)</text>\n",
       "<polyline fill=\"none\" points=\"478.8901,-103.5 583.5386,-103.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"531.2144\" y=\"-88.3\">(None, 10, 100)</text>\n",
       "</g>\n",
       "<!-- 8142044968&#45;&gt;8153512592 -->\n",
       "<g class=\"edge\" id=\"edge8\">\n",
       "<title>8142044968-&gt;8153512592</title>\n",
       "<path d=\"M336.1436,-162.3664C336.1436,-154.1516 336.1436,-144.6579 336.1436,-135.7252\" fill=\"none\" stroke=\"#000000\"/>\n",
       "<polygon fill=\"#000000\" points=\"339.6437,-135.6068 336.1436,-125.6068 332.6437,-135.6069 339.6437,-135.6068\" stroke=\"#000000\"/>\n",
       "</g>\n",
       "<!-- 8155934560 -->\n",
       "<g class=\"node\" id=\"node10\">\n",
       "<title>8155934560</title>\n",
       "<polygon fill=\"none\" points=\"88.7485,-.5 88.7485,-44.5 583.5386,-44.5 583.5386,-.5 88.7485,-.5\" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"255.9849\" y=\"-18.3\">time_distributed_42(dense_42): TimeDistributed(Dense)</text>\n",
       "<polyline fill=\"none\" points=\"423.2212,-.5 423.2212,-44.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"451.0557\" y=\"-29.3\">input:</text>\n",
       "<polyline fill=\"none\" points=\"423.2212,-22.5 478.8901,-22.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"451.0557\" y=\"-7.3\">output:</text>\n",
       "<polyline fill=\"none\" points=\"478.8901,-.5 478.8901,-44.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"531.2144\" y=\"-29.3\">(None, 10, 100)</text>\n",
       "<polyline fill=\"none\" points=\"478.8901,-22.5 583.5386,-22.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"531.2144\" y=\"-7.3\">(None, 10, 2)</text>\n",
       "</g>\n",
       "<!-- 8153512592&#45;&gt;8155934560 -->\n",
       "<g class=\"edge\" id=\"edge9\">\n",
       "<title>8153512592-&gt;8155934560</title>\n",
       "<path d=\"M336.1436,-81.3664C336.1436,-73.1516 336.1436,-63.6579 336.1436,-54.7252\" fill=\"none\" stroke=\"#000000\"/>\n",
       "<polygon fill=\"#000000\" points=\"339.6437,-54.6068 336.1436,-44.6068 332.6437,-54.6069 339.6437,-54.6068\" stroke=\"#000000\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>"
      ],
      "text/plain": [
       "<IPython.core.display.SVG object>"
      ]
     },
     "execution_count": 100,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model4 = build_end_to_end_model_two_tap_channel_deeper_LSTM_no_preprocessing(channel_train.shape[1], convolved_train.shape[1], channel_length, input_data_symbols_train.shape[1])\n",
    "SVG(model_to_dot(model4, show_shapes=True, show_layer_names=True).create(prog='dot', format='svg'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 101,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/200\n",
      "82/82 [==============================] - 223s - loss: 0.7945 - mean_squared_error: 0.7945 - val_loss: 0.6419 - val_mean_squared_error: 0.6419\n",
      "Epoch 2/200\n",
      "82/82 [==============================] - 218s - loss: 0.2279 - mean_squared_error: 0.2279 - val_loss: 0.0980 - val_mean_squared_error: 0.0980\n",
      "Epoch 3/200\n",
      "82/82 [==============================] - 210s - loss: 0.0858 - mean_squared_error: 0.0858 - val_loss: 0.0684 - val_mean_squared_error: 0.0684\n",
      "Epoch 4/200\n",
      "82/82 [==============================] - 200s - loss: 0.0614 - mean_squared_error: 0.0614 - val_loss: 0.0536 - val_mean_squared_error: 0.0536\n",
      "Epoch 5/200\n",
      "82/82 [==============================] - 200s - loss: 0.0518 - mean_squared_error: 0.0518 - val_loss: 0.0496 - val_mean_squared_error: 0.0496\n",
      "Epoch 6/200\n",
      "82/82 [==============================] - 201s - loss: 0.0453 - mean_squared_error: 0.0453 - val_loss: 0.0400 - val_mean_squared_error: 0.0400\n",
      "Epoch 7/200\n",
      "82/82 [==============================] - 201s - loss: 0.0381 - mean_squared_error: 0.0381 - val_loss: 0.0352 - val_mean_squared_error: 0.0352\n",
      "Epoch 8/200\n",
      "82/82 [==============================] - 201s - loss: 0.0331 - mean_squared_error: 0.0331 - val_loss: 0.0305 - val_mean_squared_error: 0.0305\n",
      "Epoch 9/200\n",
      "82/82 [==============================] - 201s - loss: 0.0302 - mean_squared_error: 0.0302 - val_loss: 0.0271 - val_mean_squared_error: 0.0271\n",
      "Epoch 10/200\n",
      "82/82 [==============================] - 200s - loss: 0.0254 - mean_squared_error: 0.0254 - val_loss: 0.0237 - val_mean_squared_error: 0.0237\n",
      "Epoch 11/200\n",
      "82/82 [==============================] - 218s - loss: 0.0219 - mean_squared_error: 0.0219 - val_loss: 0.0201 - val_mean_squared_error: 0.0201\n",
      "Epoch 12/200\n",
      "82/82 [==============================] - 216s - loss: 0.0194 - mean_squared_error: 0.0194 - val_loss: 0.0186 - val_mean_squared_error: 0.0186\n",
      "Epoch 13/200\n",
      "82/82 [==============================] - 217s - loss: 0.0164 - mean_squared_error: 0.0164 - val_loss: 0.0159 - val_mean_squared_error: 0.0159\n",
      "Epoch 14/200\n",
      "82/82 [==============================] - 220s - loss: 0.0144 - mean_squared_error: 0.0144 - val_loss: 0.0133 - val_mean_squared_error: 0.0133\n",
      "Epoch 15/200\n",
      "82/82 [==============================] - 228s - loss: 0.0140 - mean_squared_error: 0.0140 - val_loss: 0.0115 - val_mean_squared_error: 0.0115\n",
      "Epoch 16/200\n",
      "82/82 [==============================] - 224s - loss: 0.0111 - mean_squared_error: 0.0111 - val_loss: 0.0104 - val_mean_squared_error: 0.0104\n",
      "Epoch 17/200\n",
      "82/82 [==============================] - 212s - loss: 0.0111 - mean_squared_error: 0.0111 - val_loss: 0.0101 - val_mean_squared_error: 0.0101\n",
      "Epoch 18/200\n",
      "82/82 [==============================] - 213s - loss: 0.0096 - mean_squared_error: 0.0096 - val_loss: 0.0101 - val_mean_squared_error: 0.0101\n",
      "Epoch 19/200\n",
      "82/82 [==============================] - 224s - loss: 0.0083 - mean_squared_error: 0.0083 - val_loss: 0.0088 - val_mean_squared_error: 0.0088\n",
      "Epoch 20/200\n",
      "82/82 [==============================] - 220s - loss: 0.0082 - mean_squared_error: 0.0082 - val_loss: 0.0079 - val_mean_squared_error: 0.0079\n",
      "Epoch 21/200\n",
      "82/82 [==============================] - 221s - loss: 0.0077 - mean_squared_error: 0.0077 - val_loss: 0.0081 - val_mean_squared_error: 0.0081\n",
      "Epoch 22/200\n",
      "82/82 [==============================] - 229s - loss: 0.0076 - mean_squared_error: 0.0076 - val_loss: 0.0072 - val_mean_squared_error: 0.0072\n",
      "Epoch 23/200\n",
      "82/82 [==============================] - 229s - loss: 0.0075 - mean_squared_error: 0.0075 - val_loss: 0.0063 - val_mean_squared_error: 0.0063\n",
      "Epoch 24/200\n",
      "82/82 [==============================] - 224s - loss: 0.0067 - mean_squared_error: 0.0067 - val_loss: 0.0068 - val_mean_squared_error: 0.0068\n",
      "Epoch 25/200\n",
      "82/82 [==============================] - 218s - loss: 0.0061 - mean_squared_error: 0.0061 - val_loss: 0.0082 - val_mean_squared_error: 0.0082\n",
      "Epoch 26/200\n",
      "82/82 [==============================] - 210s - loss: 0.0063 - mean_squared_error: 0.0063 - val_loss: 0.0056 - val_mean_squared_error: 0.0056\n",
      "Epoch 27/200\n",
      "82/82 [==============================] - 208s - loss: 0.0057 - mean_squared_error: 0.0057 - val_loss: 0.0053 - val_mean_squared_error: 0.0053\n",
      "Epoch 28/200\n",
      "82/82 [==============================] - 208s - loss: 0.0060 - mean_squared_error: 0.0060 - val_loss: 0.0060 - val_mean_squared_error: 0.0060\n",
      "Epoch 29/200\n",
      "82/82 [==============================] - 208s - loss: 0.0048 - mean_squared_error: 0.0048 - val_loss: 0.0049 - val_mean_squared_error: 0.0049\n",
      "Epoch 30/200\n",
      "82/82 [==============================] - 207s - loss: 0.0049 - mean_squared_error: 0.0049 - val_loss: 0.0048 - val_mean_squared_error: 0.0048\n",
      "Epoch 31/200\n",
      "82/82 [==============================] - 202s - loss: 0.0049 - mean_squared_error: 0.0049 - val_loss: 0.0049 - val_mean_squared_error: 0.0049\n",
      "Epoch 32/200\n",
      "82/82 [==============================] - 203s - loss: 0.0050 - mean_squared_error: 0.0050 - val_loss: 0.0044 - val_mean_squared_error: 0.0044\n",
      "Epoch 33/200\n",
      "82/82 [==============================] - 209s - loss: 0.0054 - mean_squared_error: 0.0054 - val_loss: 0.0056 - val_mean_squared_error: 0.0056\n",
      "Epoch 34/200\n",
      "82/82 [==============================] - 207s - loss: 0.0048 - mean_squared_error: 0.0048 - val_loss: 0.0058 - val_mean_squared_error: 0.0058\n",
      "Epoch 35/200\n",
      "82/82 [==============================] - 207s - loss: 0.0050 - mean_squared_error: 0.0050 - val_loss: 0.0043 - val_mean_squared_error: 0.0043\n",
      "Epoch 36/200\n",
      "82/82 [==============================] - 208s - loss: 0.0046 - mean_squared_error: 0.0046 - val_loss: 0.0043 - val_mean_squared_error: 0.0043\n",
      "Epoch 37/200\n",
      "82/82 [==============================] - 208s - loss: 0.0047 - mean_squared_error: 0.0047 - val_loss: 0.0040 - val_mean_squared_error: 0.0040\n",
      "Epoch 38/200\n",
      "82/82 [==============================] - 216s - loss: 0.0037 - mean_squared_error: 0.0037 - val_loss: 0.0046 - val_mean_squared_error: 0.0046\n",
      "Epoch 39/200\n",
      "82/82 [==============================] - 200s - loss: 0.0044 - mean_squared_error: 0.0044 - val_loss: 0.0036 - val_mean_squared_error: 0.0036\n",
      "Epoch 40/200\n",
      "82/82 [==============================] - 201s - loss: 0.0039 - mean_squared_error: 0.0039 - val_loss: 0.0036 - val_mean_squared_error: 0.0036\n",
      "Epoch 41/200\n",
      "82/82 [==============================] - 201s - loss: 0.0038 - mean_squared_error: 0.0038 - val_loss: 0.0044 - val_mean_squared_error: 0.0044\n",
      "Epoch 42/200\n",
      "82/82 [==============================] - 201s - loss: 0.0037 - mean_squared_error: 0.0037 - val_loss: 0.0042 - val_mean_squared_error: 0.0042\n",
      "Epoch 43/200\n",
      "82/82 [==============================] - 201s - loss: 0.0042 - mean_squared_error: 0.0042 - val_loss: 0.0035 - val_mean_squared_error: 0.0035\n",
      "Epoch 44/200\n",
      "82/82 [==============================] - 211s - loss: 0.0034 - mean_squared_error: 0.0034 - val_loss: 0.0036 - val_mean_squared_error: 0.0036\n",
      "Epoch 45/200\n",
      "82/82 [==============================] - 221s - loss: 0.0037 - mean_squared_error: 0.0037 - val_loss: 0.0036 - val_mean_squared_error: 0.0036\n",
      "Epoch 46/200\n",
      "82/82 [==============================] - 214s - loss: 0.0037 - mean_squared_error: 0.0037 - val_loss: 0.0035 - val_mean_squared_error: 0.0035\n",
      "Epoch 47/200\n",
      "82/82 [==============================] - 212s - loss: 0.0038 - mean_squared_error: 0.0038 - val_loss: 0.0038 - val_mean_squared_error: 0.0038\n",
      "Epoch 48/200\n",
      "82/82 [==============================] - 212s - loss: 0.0034 - mean_squared_error: 0.0034 - val_loss: 0.0033 - val_mean_squared_error: 0.0033\n",
      "Epoch 49/200\n",
      "82/82 [==============================] - 209s - loss: 0.0034 - mean_squared_error: 0.0034 - val_loss: 0.0032 - val_mean_squared_error: 0.0032\n",
      "Epoch 50/200\n",
      "82/82 [==============================] - 219s - loss: 0.0056 - mean_squared_error: 0.0056 - val_loss: 0.0029 - val_mean_squared_error: 0.0029\n",
      "Epoch 51/200\n",
      "82/82 [==============================] - 210s - loss: 0.0032 - mean_squared_error: 0.0032 - val_loss: 0.0027 - val_mean_squared_error: 0.0027\n",
      "Epoch 52/200\n",
      "82/82 [==============================] - 218s - loss: 0.0030 - mean_squared_error: 0.0030 - val_loss: 0.0033 - val_mean_squared_error: 0.0033\n",
      "Epoch 53/200\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "82/82 [==============================] - 215s - loss: 0.0029 - mean_squared_error: 0.0029 - val_loss: 0.0028 - val_mean_squared_error: 0.0028\n",
      "Epoch 54/200\n",
      "82/82 [==============================] - 205s - loss: 0.0029 - mean_squared_error: 0.0029 - val_loss: 0.0028 - val_mean_squared_error: 0.0028\n",
      "Epoch 55/200\n",
      "82/82 [==============================] - 214s - loss: 0.0035 - mean_squared_error: 0.0035 - val_loss: 0.0026 - val_mean_squared_error: 0.0026\n",
      "Epoch 56/200\n",
      "82/82 [==============================] - 226s - loss: 0.0030 - mean_squared_error: 0.0030 - val_loss: 0.0028 - val_mean_squared_error: 0.0028\n",
      "Epoch 57/200\n",
      "82/82 [==============================] - 215s - loss: 0.0033 - mean_squared_error: 0.0033 - val_loss: 0.0028 - val_mean_squared_error: 0.0028\n",
      "Epoch 58/200\n",
      "82/82 [==============================] - 210s - loss: 0.0026 - mean_squared_error: 0.0026 - val_loss: 0.0028 - val_mean_squared_error: 0.0028\n",
      "Epoch 59/200\n",
      "82/82 [==============================] - 217s - loss: 0.0031 - mean_squared_error: 0.0031 - val_loss: 0.0028 - val_mean_squared_error: 0.0028\n",
      "Epoch 60/200\n",
      "82/82 [==============================] - 207s - loss: 0.0030 - mean_squared_error: 0.0030 - val_loss: 0.0025 - val_mean_squared_error: 0.0025\n",
      "Epoch 61/200\n",
      "82/82 [==============================] - 209s - loss: 0.0028 - mean_squared_error: 0.0028 - val_loss: 0.0032 - val_mean_squared_error: 0.0032\n",
      "Epoch 62/200\n",
      "82/82 [==============================] - 213s - loss: 0.0029 - mean_squared_error: 0.0029 - val_loss: 0.0024 - val_mean_squared_error: 0.0024\n",
      "Epoch 63/200\n",
      "82/82 [==============================] - 213s - loss: 0.0025 - mean_squared_error: 0.0025 - val_loss: 0.0031 - val_mean_squared_error: 0.0031\n",
      "Epoch 64/200\n",
      "82/82 [==============================] - 213s - loss: 0.0028 - mean_squared_error: 0.0028 - val_loss: 0.0025 - val_mean_squared_error: 0.0025\n",
      "Epoch 65/200\n",
      "82/82 [==============================] - 216s - loss: 0.0036 - mean_squared_error: 0.0036 - val_loss: 0.0055 - val_mean_squared_error: 0.0055\n",
      "Epoch 66/200\n",
      "82/82 [==============================] - 216s - loss: 0.0028 - mean_squared_error: 0.0028 - val_loss: 0.0027 - val_mean_squared_error: 0.0027\n",
      "Epoch 67/200\n",
      "82/82 [==============================] - 223s - loss: 0.0027 - mean_squared_error: 0.0027 - val_loss: 0.0054 - val_mean_squared_error: 0.0054\n",
      "Epoch 68/200\n",
      "82/82 [==============================] - 216s - loss: 0.0031 - mean_squared_error: 0.0031 - val_loss: 0.0036 - val_mean_squared_error: 0.0036\n",
      "Epoch 69/200\n",
      "82/82 [==============================] - 217s - loss: 0.0028 - mean_squared_error: 0.0028 - val_loss: 0.0027 - val_mean_squared_error: 0.0027\n",
      "Epoch 70/200\n",
      "82/82 [==============================] - 219s - loss: 0.0026 - mean_squared_error: 0.0026 - val_loss: 0.0023 - val_mean_squared_error: 0.0023\n",
      "Epoch 71/200\n",
      "82/82 [==============================] - 217s - loss: 0.0023 - mean_squared_error: 0.0023 - val_loss: 0.0021 - val_mean_squared_error: 0.0021\n",
      "Epoch 72/200\n",
      "82/82 [==============================] - 214s - loss: 0.0026 - mean_squared_error: 0.0026 - val_loss: 0.0023 - val_mean_squared_error: 0.0023\n",
      "Epoch 73/200\n",
      "82/82 [==============================] - 215s - loss: 0.0027 - mean_squared_error: 0.0027 - val_loss: 0.0026 - val_mean_squared_error: 0.0026\n",
      "Epoch 74/200\n",
      "82/82 [==============================] - 210s - loss: 0.0023 - mean_squared_error: 0.0023 - val_loss: 0.0024 - val_mean_squared_error: 0.0024\n",
      "Epoch 75/200\n",
      "82/82 [==============================] - 212s - loss: 0.0022 - mean_squared_error: 0.0022 - val_loss: 0.0041 - val_mean_squared_error: 0.0041\n",
      "Epoch 76/200\n",
      "82/82 [==============================] - 212s - loss: 0.0028 - mean_squared_error: 0.0028 - val_loss: 0.0021 - val_mean_squared_error: 0.0021\n",
      "Epoch 77/200\n",
      "82/82 [==============================] - 216s - loss: 0.0022 - mean_squared_error: 0.0022 - val_loss: 0.0023 - val_mean_squared_error: 0.0023\n",
      "Epoch 78/200\n",
      "82/82 [==============================] - 212s - loss: 0.0026 - mean_squared_error: 0.0026 - val_loss: 0.0022 - val_mean_squared_error: 0.0022\n",
      "Epoch 79/200\n",
      "82/82 [==============================] - 209s - loss: 0.0024 - mean_squared_error: 0.0024 - val_loss: 0.0021 - val_mean_squared_error: 0.0021\n",
      "Epoch 80/200\n",
      "82/82 [==============================] - 211s - loss: 0.0026 - mean_squared_error: 0.0026 - val_loss: 0.0022 - val_mean_squared_error: 0.0022\n",
      "Epoch 81/200\n",
      "82/82 [==============================] - 223s - loss: 0.0023 - mean_squared_error: 0.0023 - val_loss: 0.0025 - val_mean_squared_error: 0.0025\n",
      "Epoch 82/200\n",
      "82/82 [==============================] - 227s - loss: 0.0022 - mean_squared_error: 0.0022 - val_loss: 0.0020 - val_mean_squared_error: 0.0020\n",
      "Epoch 83/200\n",
      "82/82 [==============================] - 223s - loss: 0.0024 - mean_squared_error: 0.0024 - val_loss: 0.0018 - val_mean_squared_error: 0.0018\n",
      "Epoch 84/200\n",
      "82/82 [==============================] - 223s - loss: 0.0022 - mean_squared_error: 0.0022 - val_loss: 0.0034 - val_mean_squared_error: 0.0034\n",
      "Epoch 85/200\n",
      "82/82 [==============================] - 223s - loss: 0.0022 - mean_squared_error: 0.0022 - val_loss: 0.0022 - val_mean_squared_error: 0.0022\n",
      "Epoch 86/200\n",
      "82/82 [==============================] - 226s - loss: 0.0023 - mean_squared_error: 0.0023 - val_loss: 0.0021 - val_mean_squared_error: 0.0021\n",
      "Epoch 87/200\n",
      "82/82 [==============================] - 229s - loss: 0.0026 - mean_squared_error: 0.0026 - val_loss: 0.0024 - val_mean_squared_error: 0.0024\n",
      "Epoch 88/200\n",
      "82/82 [==============================] - 215s - loss: 0.0018 - mean_squared_error: 0.0018 - val_loss: 0.0018 - val_mean_squared_error: 0.0018\n",
      "Epoch 89/200\n",
      "82/82 [==============================] - 214s - loss: 0.0022 - mean_squared_error: 0.0022 - val_loss: 0.0019 - val_mean_squared_error: 0.0019\n",
      "Epoch 90/200\n",
      "82/82 [==============================] - 216s - loss: 0.0026 - mean_squared_error: 0.0026 - val_loss: 0.0018 - val_mean_squared_error: 0.0018\n",
      "Epoch 91/200\n",
      "82/82 [==============================] - 223s - loss: 0.0017 - mean_squared_error: 0.0017 - val_loss: 0.0018 - val_mean_squared_error: 0.0018\n",
      "Epoch 92/200\n",
      "82/82 [==============================] - 225s - loss: 0.0025 - mean_squared_error: 0.0025 - val_loss: 0.0019 - val_mean_squared_error: 0.0019\n",
      "Epoch 93/200\n",
      "82/82 [==============================] - 210s - loss: 0.0028 - mean_squared_error: 0.0028 - val_loss: 0.0018 - val_mean_squared_error: 0.0018\n",
      "Epoch 94/200\n",
      "82/82 [==============================] - 216s - loss: 0.0024 - mean_squared_error: 0.0024 - val_loss: 0.0018 - val_mean_squared_error: 0.0018\n",
      "Epoch 95/200\n",
      "82/82 [==============================] - 212s - loss: 0.0019 - mean_squared_error: 0.0019 - val_loss: 0.0020 - val_mean_squared_error: 0.0020\n",
      "Epoch 96/200\n",
      "82/82 [==============================] - 203s - loss: 0.0020 - mean_squared_error: 0.0020 - val_loss: 0.0023 - val_mean_squared_error: 0.0023\n",
      "Epoch 97/200\n",
      "82/82 [==============================] - 201s - loss: 0.0021 - mean_squared_error: 0.0021 - val_loss: 0.0020 - val_mean_squared_error: 0.0020\n",
      "Epoch 98/200\n",
      "82/82 [==============================] - 200s - loss: 0.0025 - mean_squared_error: 0.0025 - val_loss: 0.0019 - val_mean_squared_error: 0.0019\n",
      "Epoch 99/200\n",
      "82/82 [==============================] - 201s - loss: 0.0023 - mean_squared_error: 0.0023 - val_loss: 0.0028 - val_mean_squared_error: 0.0028\n",
      "Epoch 100/200\n",
      "82/82 [==============================] - 202s - loss: 0.0018 - mean_squared_error: 0.0018 - val_loss: 0.0016 - val_mean_squared_error: 0.0016\n",
      "Epoch 101/200\n",
      "82/82 [==============================] - 201s - loss: 0.0021 - mean_squared_error: 0.0021 - val_loss: 0.0022 - val_mean_squared_error: 0.0022\n",
      "Epoch 102/200\n",
      "82/82 [==============================] - 201s - loss: 0.0018 - mean_squared_error: 0.0018 - val_loss: 0.0017 - val_mean_squared_error: 0.0017\n",
      "Epoch 103/200\n",
      "82/82 [==============================] - 201s - loss: 0.0023 - mean_squared_error: 0.0023 - val_loss: 0.0017 - val_mean_squared_error: 0.0017\n",
      "Epoch 104/200\n",
      "82/82 [==============================] - 200s - loss: 0.0018 - mean_squared_error: 0.0018 - val_loss: 0.0016 - val_mean_squared_error: 0.0016\n",
      "Epoch 105/200\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "82/82 [==============================] - 201s - loss: 0.0018 - mean_squared_error: 0.0018 - val_loss: 0.0016 - val_mean_squared_error: 0.0016\n",
      "Epoch 106/200\n",
      "82/82 [==============================] - 201s - loss: 0.0023 - mean_squared_error: 0.0023 - val_loss: 0.0021 - val_mean_squared_error: 0.0021\n",
      "Epoch 107/200\n",
      "82/82 [==============================] - 200s - loss: 0.0019 - mean_squared_error: 0.0019 - val_loss: 0.0020 - val_mean_squared_error: 0.0020\n",
      "Epoch 108/200\n",
      "82/82 [==============================] - 201s - loss: 0.0021 - mean_squared_error: 0.0021 - val_loss: 0.0018 - val_mean_squared_error: 0.0018\n",
      "Epoch 109/200\n",
      "82/82 [==============================] - 201s - loss: 0.0021 - mean_squared_error: 0.0021 - val_loss: 0.0024 - val_mean_squared_error: 0.0024\n",
      "Epoch 110/200\n",
      "82/82 [==============================] - 200s - loss: 0.0021 - mean_squared_error: 0.0021 - val_loss: 0.0017 - val_mean_squared_error: 0.0017\n",
      "Epoch 111/200\n",
      "82/82 [==============================] - 201s - loss: 0.0021 - mean_squared_error: 0.0021 - val_loss: 0.0016 - val_mean_squared_error: 0.0016\n",
      "Epoch 112/200\n",
      "82/82 [==============================] - 201s - loss: 0.0021 - mean_squared_error: 0.0021 - val_loss: 0.0016 - val_mean_squared_error: 0.0016\n",
      "Epoch 113/200\n",
      "82/82 [==============================] - 201s - loss: 0.0018 - mean_squared_error: 0.0018 - val_loss: 0.0016 - val_mean_squared_error: 0.0016\n",
      "Epoch 114/200\n",
      "82/82 [==============================] - 201s - loss: 0.0021 - mean_squared_error: 0.0021 - val_loss: 0.0017 - val_mean_squared_error: 0.0017\n",
      "Epoch 115/200\n",
      "82/82 [==============================] - 200s - loss: 0.0017 - mean_squared_error: 0.0017 - val_loss: 0.0016 - val_mean_squared_error: 0.0016\n",
      "Epoch 116/200\n",
      "82/82 [==============================] - 201s - loss: 0.0021 - mean_squared_error: 0.0021 - val_loss: 0.0017 - val_mean_squared_error: 0.0017\n",
      "Epoch 117/200\n",
      "82/82 [==============================] - 202s - loss: 0.0017 - mean_squared_error: 0.0017 - val_loss: 0.0022 - val_mean_squared_error: 0.0022\n",
      "Epoch 118/200\n",
      "82/82 [==============================] - 202s - loss: 0.0019 - mean_squared_error: 0.0019 - val_loss: 0.0016 - val_mean_squared_error: 0.0016\n",
      "Epoch 119/200\n",
      "82/82 [==============================] - 201s - loss: 0.0019 - mean_squared_error: 0.0019 - val_loss: 0.0014 - val_mean_squared_error: 0.0014\n",
      "Epoch 120/200\n",
      "82/82 [==============================] - 201s - loss: 0.0016 - mean_squared_error: 0.0016 - val_loss: 0.0017 - val_mean_squared_error: 0.0017\n",
      "Epoch 121/200\n",
      "82/82 [==============================] - 201s - loss: 0.0015 - mean_squared_error: 0.0015 - val_loss: 0.0016 - val_mean_squared_error: 0.0016\n",
      "Epoch 122/200\n",
      "82/82 [==============================] - 201s - loss: 0.0017 - mean_squared_error: 0.0017 - val_loss: 0.0016 - val_mean_squared_error: 0.0016\n",
      "Epoch 123/200\n",
      "82/82 [==============================] - 201s - loss: 0.0013 - mean_squared_error: 0.0013 - val_loss: 0.0016 - val_mean_squared_error: 0.0016\n",
      "Epoch 124/200\n",
      "82/82 [==============================] - 200s - loss: 0.0018 - mean_squared_error: 0.0018 - val_loss: 0.0017 - val_mean_squared_error: 0.0017\n",
      "Epoch 125/200\n",
      "82/82 [==============================] - 201s - loss: 0.0017 - mean_squared_error: 0.0017 - val_loss: 0.0016 - val_mean_squared_error: 0.0016\n",
      "Epoch 126/200\n",
      "82/82 [==============================] - 201s - loss: 0.0020 - mean_squared_error: 0.0020 - val_loss: 0.0018 - val_mean_squared_error: 0.0018\n",
      "Epoch 127/200\n",
      "82/82 [==============================] - 201s - loss: 0.0019 - mean_squared_error: 0.0019 - val_loss: 0.0026 - val_mean_squared_error: 0.0026\n",
      "Epoch 128/200\n",
      "82/82 [==============================] - 201s - loss: 0.0018 - mean_squared_error: 0.0018 - val_loss: 0.0018 - val_mean_squared_error: 0.0018\n",
      "Epoch 129/200\n",
      "82/82 [==============================] - 201s - loss: 0.0021 - mean_squared_error: 0.0021 - val_loss: 0.0017 - val_mean_squared_error: 0.0017\n",
      "Epoch 130/200\n",
      "82/82 [==============================] - 201s - loss: 0.0017 - mean_squared_error: 0.0017 - val_loss: 0.0015 - val_mean_squared_error: 0.0015\n",
      "Epoch 131/200\n",
      "82/82 [==============================] - 201s - loss: 0.0020 - mean_squared_error: 0.0020 - val_loss: 0.0018 - val_mean_squared_error: 0.0018\n",
      "Epoch 132/200\n",
      "82/82 [==============================] - 200s - loss: 0.0020 - mean_squared_error: 0.0020 - val_loss: 0.0015 - val_mean_squared_error: 0.0015\n",
      "Epoch 133/200\n",
      "82/82 [==============================] - 201s - loss: 0.0018 - mean_squared_error: 0.0018 - val_loss: 0.0016 - val_mean_squared_error: 0.0016\n",
      "Epoch 134/200\n",
      "82/82 [==============================] - 200s - loss: 0.0018 - mean_squared_error: 0.0018 - val_loss: 0.0019 - val_mean_squared_error: 0.0019\n",
      "Epoch 135/200\n",
      "82/82 [==============================] - 202s - loss: 0.0021 - mean_squared_error: 0.0021 - val_loss: 0.0016 - val_mean_squared_error: 0.0016\n",
      "Epoch 136/200\n",
      "82/82 [==============================] - 201s - loss: 0.0018 - mean_squared_error: 0.0018 - val_loss: 0.0015 - val_mean_squared_error: 0.0015\n",
      "Epoch 137/200\n",
      "82/82 [==============================] - 201s - loss: 0.0014 - mean_squared_error: 0.0014 - val_loss: 0.0016 - val_mean_squared_error: 0.0016\n",
      "Epoch 138/200\n",
      "82/82 [==============================] - 200s - loss: 0.0015 - mean_squared_error: 0.0015 - val_loss: 0.0016 - val_mean_squared_error: 0.0016\n",
      "Epoch 139/200\n",
      "82/82 [==============================] - 200s - loss: 0.0014 - mean_squared_error: 0.0014 - val_loss: 0.0019 - val_mean_squared_error: 0.0019\n",
      "Epoch 140/200\n",
      "82/82 [==============================] - 200s - loss: 0.0016 - mean_squared_error: 0.0016 - val_loss: 0.0020 - val_mean_squared_error: 0.0020\n",
      "Epoch 141/200\n",
      "82/82 [==============================] - 201s - loss: 0.0013 - mean_squared_error: 0.0013 - val_loss: 0.0013 - val_mean_squared_error: 0.0013\n",
      "Epoch 142/200\n",
      "82/82 [==============================] - 201s - loss: 0.0015 - mean_squared_error: 0.0015 - val_loss: 0.0016 - val_mean_squared_error: 0.0016\n",
      "Epoch 143/200\n",
      "82/82 [==============================] - 200s - loss: 0.0014 - mean_squared_error: 0.0014 - val_loss: 0.0013 - val_mean_squared_error: 0.0013\n",
      "Epoch 144/200\n",
      "82/82 [==============================] - 200s - loss: 0.0018 - mean_squared_error: 0.0018 - val_loss: 0.0029 - val_mean_squared_error: 0.0029\n",
      "Epoch 145/200\n",
      "82/82 [==============================] - 201s - loss: 0.0018 - mean_squared_error: 0.0018 - val_loss: 0.0023 - val_mean_squared_error: 0.0023\n",
      "Epoch 146/200\n",
      "82/82 [==============================] - 201s - loss: 0.0016 - mean_squared_error: 0.0016 - val_loss: 0.0017 - val_mean_squared_error: 0.0017\n",
      "Epoch 147/200\n",
      "82/82 [==============================] - 201s - loss: 0.0018 - mean_squared_error: 0.0018 - val_loss: 0.0020 - val_mean_squared_error: 0.0020\n",
      "Epoch 148/200\n",
      "82/82 [==============================] - 201s - loss: 0.0015 - mean_squared_error: 0.0015 - val_loss: 0.0013 - val_mean_squared_error: 0.0013\n",
      "Epoch 149/200\n",
      "82/82 [==============================] - 201s - loss: 0.0013 - mean_squared_error: 0.0013 - val_loss: 0.0018 - val_mean_squared_error: 0.0018\n",
      "Epoch 150/200\n",
      "82/82 [==============================] - 201s - loss: 0.0016 - mean_squared_error: 0.0016 - val_loss: 0.0015 - val_mean_squared_error: 0.0015\n",
      "Epoch 151/200\n",
      "82/82 [==============================] - 201s - loss: 0.0018 - mean_squared_error: 0.0018 - val_loss: 0.0019 - val_mean_squared_error: 0.0019\n",
      "Epoch 152/200\n",
      "82/82 [==============================] - 201s - loss: 0.0014 - mean_squared_error: 0.0014 - val_loss: 0.0013 - val_mean_squared_error: 0.0013\n",
      "Epoch 153/200\n",
      "82/82 [==============================] - 201s - loss: 0.0016 - mean_squared_error: 0.0016 - val_loss: 0.0013 - val_mean_squared_error: 0.0013\n",
      "Epoch 154/200\n",
      "82/82 [==============================] - 203s - loss: 0.0018 - mean_squared_error: 0.0018 - val_loss: 0.0014 - val_mean_squared_error: 0.0014\n",
      "Epoch 155/200\n",
      "82/82 [==============================] - 201s - loss: 0.0019 - mean_squared_error: 0.0019 - val_loss: 0.0017 - val_mean_squared_error: 0.0017\n",
      "Epoch 156/200\n",
      "82/82 [==============================] - 201s - loss: 0.0017 - mean_squared_error: 0.0017 - val_loss: 0.0020 - val_mean_squared_error: 0.0020\n",
      "Epoch 157/200\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "82/82 [==============================] - 201s - loss: 0.0016 - mean_squared_error: 0.0016 - val_loss: 0.0015 - val_mean_squared_error: 0.0015\n",
      "Epoch 158/200\n",
      "82/82 [==============================] - 200s - loss: 0.0014 - mean_squared_error: 0.0014 - val_loss: 0.0016 - val_mean_squared_error: 0.0016\n",
      "Epoch 159/200\n",
      "82/82 [==============================] - 200s - loss: 0.0018 - mean_squared_error: 0.0018 - val_loss: 0.0013 - val_mean_squared_error: 0.0013\n",
      "Epoch 160/200\n",
      "82/82 [==============================] - 201s - loss: 0.0016 - mean_squared_error: 0.0016 - val_loss: 0.0015 - val_mean_squared_error: 0.0015\n",
      "Epoch 161/200\n",
      "82/82 [==============================] - 201s - loss: 0.0016 - mean_squared_error: 0.0016 - val_loss: 0.0012 - val_mean_squared_error: 0.0012\n",
      "Epoch 162/200\n",
      "82/82 [==============================] - 200s - loss: 0.0015 - mean_squared_error: 0.0015 - val_loss: 0.0016 - val_mean_squared_error: 0.0016\n",
      "Epoch 163/200\n",
      "82/82 [==============================] - 201s - loss: 0.0014 - mean_squared_error: 0.0014 - val_loss: 0.0014 - val_mean_squared_error: 0.0014\n",
      "Epoch 164/200\n",
      "82/82 [==============================] - 200s - loss: 0.0015 - mean_squared_error: 0.0015 - val_loss: 0.0012 - val_mean_squared_error: 0.0012\n",
      "Epoch 165/200\n",
      "82/82 [==============================] - 201s - loss: 0.0015 - mean_squared_error: 0.0015 - val_loss: 0.0013 - val_mean_squared_error: 0.0013\n",
      "Epoch 166/200\n",
      "82/82 [==============================] - 201s - loss: 0.0013 - mean_squared_error: 0.0013 - val_loss: 0.0015 - val_mean_squared_error: 0.0015\n",
      "Epoch 167/200\n",
      "82/82 [==============================] - 201s - loss: 0.0012 - mean_squared_error: 0.0012 - val_loss: 0.0014 - val_mean_squared_error: 0.0014\n",
      "Epoch 168/200\n",
      "82/82 [==============================] - 201s - loss: 0.0017 - mean_squared_error: 0.0017 - val_loss: 0.0014 - val_mean_squared_error: 0.0014\n",
      "Epoch 169/200\n",
      "82/82 [==============================] - 201s - loss: 0.0019 - mean_squared_error: 0.0019 - val_loss: 0.0016 - val_mean_squared_error: 0.0016\n",
      "Epoch 170/200\n",
      "82/82 [==============================] - 202s - loss: 0.0014 - mean_squared_error: 0.0014 - val_loss: 0.0012 - val_mean_squared_error: 0.0012\n",
      "Epoch 171/200\n",
      "82/82 [==============================] - 201s - loss: 0.0011 - mean_squared_error: 0.0011 - val_loss: 0.0012 - val_mean_squared_error: 0.0012\n",
      "Epoch 172/200\n",
      "82/82 [==============================] - 201s - loss: 0.0022 - mean_squared_error: 0.0022 - val_loss: 0.0015 - val_mean_squared_error: 0.0015\n",
      "Epoch 173/200\n",
      "82/82 [==============================] - 200s - loss: 0.0014 - mean_squared_error: 0.0014 - val_loss: 0.0013 - val_mean_squared_error: 0.0013\n",
      "Epoch 174/200\n",
      "82/82 [==============================] - 200s - loss: 0.0014 - mean_squared_error: 0.0014 - val_loss: 0.0013 - val_mean_squared_error: 0.0013\n",
      "Epoch 175/200\n",
      "82/82 [==============================] - 200s - loss: 0.0014 - mean_squared_error: 0.0014 - val_loss: 0.0012 - val_mean_squared_error: 0.0012\n",
      "Epoch 176/200\n",
      "82/82 [==============================] - 201s - loss: 0.0014 - mean_squared_error: 0.0014 - val_loss: 0.0013 - val_mean_squared_error: 0.0013\n",
      "Epoch 177/200\n",
      "82/82 [==============================] - 200s - loss: 0.0016 - mean_squared_error: 0.0016 - val_loss: 0.0012 - val_mean_squared_error: 0.0012\n",
      "Epoch 178/200\n",
      "82/82 [==============================] - 200s - loss: 0.0015 - mean_squared_error: 0.0015 - val_loss: 0.0013 - val_mean_squared_error: 0.0013\n",
      "Epoch 179/200\n",
      "82/82 [==============================] - 200s - loss: 0.0011 - mean_squared_error: 0.0011 - val_loss: 0.0013 - val_mean_squared_error: 0.0013\n",
      "Epoch 180/200\n",
      "82/82 [==============================] - 200s - loss: 0.0013 - mean_squared_error: 0.0013 - val_loss: 0.0021 - val_mean_squared_error: 0.0021\n",
      "Epoch 181/200\n",
      "82/82 [==============================] - 200s - loss: 0.0018 - mean_squared_error: 0.0018 - val_loss: 0.0020 - val_mean_squared_error: 0.0020\n",
      "Epoch 182/200\n",
      "82/82 [==============================] - 200s - loss: 0.0013 - mean_squared_error: 0.0013 - val_loss: 0.0012 - val_mean_squared_error: 0.0012\n",
      "Epoch 183/200\n",
      "82/82 [==============================] - 200s - loss: 0.0011 - mean_squared_error: 0.0011 - val_loss: 0.0011 - val_mean_squared_error: 0.0011\n",
      "Epoch 184/200\n",
      "82/82 [==============================] - 200s - loss: 0.0013 - mean_squared_error: 0.0013 - val_loss: 0.0013 - val_mean_squared_error: 0.0013\n",
      "Epoch 185/200\n",
      "82/82 [==============================] - 200s - loss: 0.0015 - mean_squared_error: 0.0015 - val_loss: 0.0015 - val_mean_squared_error: 0.0015\n",
      "Epoch 186/200\n",
      "82/82 [==============================] - 201s - loss: 0.0014 - mean_squared_error: 0.0014 - val_loss: 0.0015 - val_mean_squared_error: 0.0015\n",
      "Epoch 187/200\n",
      "82/82 [==============================] - 201s - loss: 0.0015 - mean_squared_error: 0.0015 - val_loss: 0.0011 - val_mean_squared_error: 0.0011\n",
      "Epoch 188/200\n",
      "82/82 [==============================] - 200s - loss: 0.0017 - mean_squared_error: 0.0017 - val_loss: 0.0015 - val_mean_squared_error: 0.0015\n",
      "Epoch 189/200\n",
      "82/82 [==============================] - 201s - loss: 0.0017 - mean_squared_error: 0.0017 - val_loss: 0.0012 - val_mean_squared_error: 0.0012\n",
      "Epoch 190/200\n",
      "20/82 [======>.......................] - ETA: 139s - loss: 0.0014 - mean_squared_error: 0.0014"
     ]
    },
    {
     "ename": "KeyboardInterrupt",
     "evalue": "",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mKeyboardInterrupt\u001b[0m                         Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-101-87a30c3cdfe3>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mhistory_model4\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mmodel4\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfit_generator\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata_generator\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msteps_per_epoch\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mtrain_size\u001b[0m \u001b[0;34m//\u001b[0m \u001b[0mbatch_size\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mvalidation_data\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mchannel_test\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mconvolved_test\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0minput_data_symbols_test\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mepochs\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m200\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/keras/legacy/interfaces.py\u001b[0m in \u001b[0;36mwrapper\u001b[0;34m(*args, **kwargs)\u001b[0m\n\u001b[1;32m     85\u001b[0m                 warnings.warn('Update your `' + object_name +\n\u001b[1;32m     86\u001b[0m                               '` call to the Keras 2 API: ' + signature, stacklevel=2)\n\u001b[0;32m---> 87\u001b[0;31m             \u001b[0;32mreturn\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     88\u001b[0m         \u001b[0mwrapper\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_original_function\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     89\u001b[0m         \u001b[0;32mreturn\u001b[0m \u001b[0mwrapper\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/keras/engine/training.py\u001b[0m in \u001b[0;36mfit_generator\u001b[0;34m(self, generator, steps_per_epoch, epochs, verbose, callbacks, validation_data, validation_steps, class_weight, max_queue_size, workers, use_multiprocessing, shuffle, initial_epoch)\u001b[0m\n\u001b[1;32m   2009\u001b[0m                 \u001b[0mbatch_index\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   2010\u001b[0m                 \u001b[0;32mwhile\u001b[0m \u001b[0msteps_done\u001b[0m \u001b[0;34m<\u001b[0m \u001b[0msteps_per_epoch\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2011\u001b[0;31m                     \u001b[0mgenerator_output\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnext\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0moutput_generator\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m   2012\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   2013\u001b[0m                     \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mhasattr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgenerator_output\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'__len__'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/keras/utils/data_utils.py\u001b[0m in \u001b[0;36mget\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m    503\u001b[0m         \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    504\u001b[0m             \u001b[0;32mwhile\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mis_running\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 505\u001b[0;31m                 \u001b[0minputs\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mqueue\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mblock\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    506\u001b[0m                 \u001b[0;32mif\u001b[0m \u001b[0minputs\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    507\u001b[0m                     \u001b[0;32myield\u001b[0m \u001b[0minputs\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/queue.py\u001b[0m in \u001b[0;36mget\u001b[0;34m(self, block, timeout)\u001b[0m\n\u001b[1;32m    162\u001b[0m             \u001b[0;32melif\u001b[0m \u001b[0mtimeout\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    163\u001b[0m                 \u001b[0;32mwhile\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_qsize\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 164\u001b[0;31m                     \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnot_empty\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mwait\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    165\u001b[0m             \u001b[0;32melif\u001b[0m \u001b[0mtimeout\u001b[0m \u001b[0;34m<\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    166\u001b[0m                 \u001b[0;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"'timeout' must be a non-negative number\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/threading.py\u001b[0m in \u001b[0;36mwait\u001b[0;34m(self, timeout)\u001b[0m\n\u001b[1;32m    293\u001b[0m         \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m    \u001b[0;31m# restore state no matter what (e.g., KeyboardInterrupt)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    294\u001b[0m             \u001b[0;32mif\u001b[0m \u001b[0mtimeout\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 295\u001b[0;31m                 \u001b[0mwaiter\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0macquire\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    296\u001b[0m                 \u001b[0mgotit\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    297\u001b[0m             \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mKeyboardInterrupt\u001b[0m: "
     ]
    }
   ],
   "source": [
    "history_model4 = model4.fit_generator(data_generator, steps_per_epoch=train_size // batch_size, validation_data=([channel_test, convolved_test], [input_data_symbols_test]), epochs=200)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 128,
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'history_model4s' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-128-b6c5038ebed5>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mplot\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlog10\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mhistory_model4s\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mhistory\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'loss'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      2\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mplot\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlog10\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mhistory_model4s\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mhistory\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'val_loss'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      3\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtitle\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'model4 loss (deeper LSTM with no channel preprocessing)'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      4\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mylabel\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'loss'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      5\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mxlabel\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'epoch'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mNameError\u001b[0m: name 'history_model4s' is not defined"
     ]
    }
   ],
   "source": [
    " "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 110,
   "metadata": {},
   "outputs": [],
   "source": [
    "predictions4 = model4.predict([channel_test, convolved_test])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 111,
   "metadata": {},
   "outputs": [],
   "source": [
    "def calc_accuracy(original, predictions):\n",
    "    return np.sum(original == predictions) / (original.shape[0] * original.shape[1])\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 112,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[-0.89329724  0.44946639]\n",
      " [-0.89329724  0.44946639]\n",
      " [-0.89329724  0.44946639]\n",
      " ...\n",
      " [ 0.6832927  -0.73014456]\n",
      " [ 0.6832927  -0.73014456]\n",
      " [ 0.6832927  -0.73014456]]\n",
      "(210000, 10, 2)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "0.9993792857142857"
      ]
     },
     "execution_count": 112,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rounded_predictions4 = np.where(predictions4 > 0, 1, -1)\n",
    "print(channel_test)\n",
    "print(rounded_predictions4.shape)\n",
    "# print(rounded_predictions4.shape, input_data_symbols_test.shape)\n",
    "new_shape = (rounded_predictions4.shape[0] * rounded_predictions4.shape[1], 2)\n",
    "rounded_predictions_reshaped4 = rounded_predictions4.reshape(new_shape)\n",
    "test_data_reshaped4 = input_data_symbols_test.reshape(new_shape)\n",
    "calc_accuracy(rounded_predictions_reshaped4, test_data_reshaped4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 113,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Channel [-0.71913158 -0.69487393]\n",
      "Prediction [ 0.9566444  -0.05529559]\n",
      "QPSK Prediction [ 1 -1]\n",
      "True QPSK [1. 1.]\n",
      "Channel [-0.71913158 -0.69487393]\n",
      "Prediction [1.0279237  0.20912854]\n",
      "QPSK Prediction [1 1]\n",
      "True QPSK [ 1. -1.]\n",
      "Channel [-0.71913158 -0.69487393]\n",
      "Prediction [ 1.0361636  -0.08044451]\n",
      "QPSK Prediction [ 1 -1]\n",
      "True QPSK [1. 1.]\n",
      "Channel [-0.71913158 -0.69487393]\n",
      "Prediction [1.015902   0.10770337]\n",
      "QPSK Prediction [1 1]\n",
      "True QPSK [ 1. -1.]\n",
      "Channel [-0.71913158 -0.69487393]\n",
      "Prediction [ 1.0314447  -0.12052026]\n",
      "QPSK Prediction [ 1 -1]\n",
      "True QPSK [1. 1.]\n",
      "Channel [-0.71913158 -0.69487393]\n",
      "Prediction [-1.04097    0.4686173]\n",
      "QPSK Prediction [-1  1]\n",
      "True QPSK [-1. -1.]\n",
      "Channel [-0.72673827 -0.68691447]\n",
      "Prediction [ 0.94050574 -0.05166346]\n",
      "QPSK Prediction [ 1 -1]\n",
      "True QPSK [1. 1.]\n",
      "Channel [0.70114398 0.71301971]\n",
      "Prediction [ 0.7482526  -0.16552939]\n",
      "QPSK Prediction [ 1 -1]\n",
      "True QPSK [1. 1.]\n",
      "Channel [0.70114398 0.71301971]\n",
      "Prediction [-0.8977239   0.06457253]\n",
      "QPSK Prediction [-1  1]\n",
      "True QPSK [-1. -1.]\n",
      "Channel [0.70114398 0.71301971]\n",
      "Prediction [-1.0336721 -0.5048162]\n",
      "QPSK Prediction [-1 -1]\n",
      "True QPSK [-1.  1.]\n",
      "Channel [ 0.71591759 -0.69818479]\n",
      "Prediction [0.20237678 1.0147241 ]\n",
      "QPSK Prediction [1 1]\n",
      "True QPSK [-1.  1.]\n",
      "Channel [ 0.71591759 -0.69818479]\n",
      "Prediction [ 0.30489197 -0.97566926]\n",
      "QPSK Prediction [ 1 -1]\n",
      "True QPSK [-1. -1.]\n",
      "Channel [ 0.71591759 -0.69818479]\n",
      "Prediction [ 0.18951918 -1.0231652 ]\n",
      "QPSK Prediction [ 1 -1]\n",
      "True QPSK [-1. -1.]\n",
      "Channel [-0.70487493 -0.70933161]\n",
      "Prediction [0.6693239 0.0494266]\n",
      "QPSK Prediction [1 1]\n",
      "True QPSK [ 1. -1.]\n",
      "Channel [-0.70487493 -0.70933161]\n",
      "Prediction [-0.9988742  -0.06879811]\n",
      "QPSK Prediction [-1 -1]\n",
      "True QPSK [-1.  1.]\n",
      "Channel [-0.70487493 -0.70933161]\n",
      "Prediction [1.0681319 0.1746626]\n",
      "QPSK Prediction [1 1]\n",
      "True QPSK [ 1. -1.]\n",
      "Channel [-0.70145876 -0.71271004]\n",
      "Prediction [-0.06934899  0.67238396]\n",
      "QPSK Prediction [-1  1]\n",
      "True QPSK [1. 1.]\n",
      "Channel [-0.73206511  0.68123467]\n",
      "Prediction [-0.97041386  0.02291554]\n",
      "QPSK Prediction [-1  1]\n",
      "True QPSK [-1. -1.]\n",
      "Channel [ 0.71424049 -0.69990036]\n",
      "Prediction [-1.037857    0.19344443]\n",
      "QPSK Prediction [-1  1]\n",
      "True QPSK [-1. -1.]\n",
      "Channel [ 0.71424049 -0.69990036]\n",
      "Prediction [-1.0181009   0.10096647]\n",
      "QPSK Prediction [-1  1]\n",
      "True QPSK [-1. -1.]\n",
      "Channel [ 0.71424049 -0.69990036]\n",
      "Prediction [1.002927   0.00747983]\n",
      "QPSK Prediction [1 1]\n",
      "True QPSK [ 1. -1.]\n",
      "Channel [ 0.71424049 -0.69990036]\n",
      "Prediction [-1.0249869   0.03350176]\n",
      "QPSK Prediction [-1  1]\n",
      "True QPSK [-1. -1.]\n",
      "Channel [-0.72185006 -0.69204948]\n",
      "Prediction [ 0.04552667 -1.0256708 ]\n",
      "QPSK Prediction [ 1 -1]\n",
      "True QPSK [-1. -1.]\n",
      "Channel [0.70920875 0.70499855]\n",
      "Prediction [-0.752995    0.07301733]\n",
      "QPSK Prediction [-1  1]\n",
      "True QPSK [-1. -1.]\n",
      "Channel [0.70920875 0.70499855]\n",
      "Prediction [ 0.90155566 -0.3990311 ]\n",
      "QPSK Prediction [ 1 -1]\n",
      "True QPSK [1. 1.]\n",
      "Channel [0.70920875 0.70499855]\n",
      "Prediction [0.98626417 0.4800038 ]\n",
      "QPSK Prediction [1 1]\n",
      "True QPSK [ 1. -1.]\n",
      "Channel [ 0.71304396 -0.70111933]\n",
      "Prediction [0.23707764 1.0330997 ]\n",
      "QPSK Prediction [1 1]\n",
      "True QPSK [-1.  1.]\n",
      "Channel [ 0.71304396 -0.70111933]\n",
      "Prediction [0.28339404 1.0120835 ]\n",
      "QPSK Prediction [1 1]\n",
      "True QPSK [-1.  1.]\n",
      "Channel [ 0.71304396 -0.70111933]\n",
      "Prediction [ 0.33608386 -0.9981233 ]\n",
      "QPSK Prediction [ 1 -1]\n",
      "True QPSK [-1. -1.]\n",
      "Channel [ 0.71304396 -0.70111933]\n",
      "Prediction [0.43955782 1.0107883 ]\n",
      "QPSK Prediction [1 1]\n",
      "True QPSK [-1.  1.]\n",
      "Channel [ 0.71304396 -0.70111933]\n",
      "Prediction [ 0.4926752 -0.9922071]\n",
      "QPSK Prediction [ 1 -1]\n",
      "True QPSK [-1. -1.]\n",
      "Channel [ 0.71304396 -0.70111933]\n",
      "Prediction [0.18699487 0.9782232 ]\n",
      "QPSK Prediction [1 1]\n",
      "True QPSK [-1.  1.]\n",
      "Channel [ 0.71304396 -0.70111933]\n",
      "Prediction [ 0.58407444 -1.034773  ]\n",
      "QPSK Prediction [ 1 -1]\n",
      "True QPSK [-1. -1.]\n",
      "Channel [ 0.71304396 -0.70111933]\n",
      "Prediction [0.3544892  0.95228815]\n",
      "QPSK Prediction [1 1]\n",
      "True QPSK [-1.  1.]\n",
      "Channel [ 0.71304396 -0.70111933]\n",
      "Prediction [ 0.3576423 -0.967641 ]\n",
      "QPSK Prediction [ 1 -1]\n",
      "True QPSK [-1. -1.]\n",
      "Channel [0.7019926  0.71218423]\n",
      "Prediction [-0.07802393 -1.0161421 ]\n",
      "QPSK Prediction [-1 -1]\n",
      "True QPSK [ 1. -1.]\n",
      "Channel [0.7019926  0.71218423]\n",
      "Prediction [ 0.11410646 -0.79624325]\n",
      "QPSK Prediction [ 1 -1]\n",
      "True QPSK [-1. -1.]\n",
      "Channel [0.7019926  0.71218423]\n",
      "Prediction [-0.01237046 -1.0330731 ]\n",
      "QPSK Prediction [-1 -1]\n",
      "True QPSK [ 1. -1.]\n",
      "Channel [0.7019926  0.71218423]\n",
      "Prediction [0.0260833 0.986354 ]\n",
      "QPSK Prediction [1 1]\n",
      "True QPSK [-1.  1.]\n",
      "Channel [0.7019926  0.71218423]\n",
      "Prediction [-0.18712083  1.045934  ]\n",
      "QPSK Prediction [-1  1]\n",
      "True QPSK [1. 1.]\n",
      "Channel [0.7019926  0.71218423]\n",
      "Prediction [0.21447308 0.63820815]\n",
      "QPSK Prediction [1 1]\n",
      "True QPSK [-1.  1.]\n",
      "Channel [0.7019926  0.71218423]\n",
      "Prediction [-0.06629248  1.0478948 ]\n",
      "QPSK Prediction [-1  1]\n",
      "True QPSK [1. 1.]\n",
      "Channel [0.7019926  0.71218423]\n",
      "Prediction [-0.0825651 -1.0259877]\n",
      "QPSK Prediction [-1 -1]\n",
      "True QPSK [ 1. -1.]\n"
     ]
    }
   ],
   "source": [
    "error_channels = []\n",
    "for i in range(rounded_predictions4.shape[0]):\n",
    "    for j in range(3):\n",
    "        if not np.array_equal(rounded_predictions4[i][j], input_data_symbols_test[i][j]):\n",
    "            print('Channel', channel_test[i])\n",
    "            print('Prediction', predictions4[i][j])\n",
    "            print('QPSK Prediction', rounded_predictions4[i][j])\n",
    "            print('True QPSK', input_data_symbols_test[i][j])\n",
    "            error_channels.append(channel_test[i])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 129,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x1fb649710>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "## This plots which channels the RNN makes errors on\n",
    "channel_errors = np.array(error_channels)\n",
    "plt.title('Channels that the RNN makes Errors')\n",
    "plt.xlabel('channel_X')\n",
    "plt.ylabel('channel_Y')\n",
    "plt.scatter(channel_errors[:, 0], channel_errors[:, 1])\n",
    "plt.savefig('Incorrect channels', bbox_inches='tight')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 126,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.metrics import mean_squared_error\n",
    "statistics_count = {(np.sqrt(2) / 2, np.sqrt(2) / 2): 0, (-np.sqrt(2) / 2, np.sqrt(2) / 2): 0, (np.sqrt(2) / 2, -np.sqrt(2) / 2): 0, (-np.sqrt(2) / 2, -np.sqrt(2) / 2): 0, (0, -1): 0}\n",
    "statistics_errors = {(np.sqrt(2) / 2, np.sqrt(2) / 2): 0, (-np.sqrt(2) / 2, np.sqrt(2) / 2): 0, (np.sqrt(2) / 2, -np.sqrt(2) / 2): 0, (-np.sqrt(2) / 2, -np.sqrt(2) / 2): 0, (0, -1): 0}\n",
    "good_channel_errors = []\n",
    "bad_channel_errors = []\n",
    "for i in range(rounded_predictions4.shape[0]):\n",
    "    for j in range(3):\n",
    "        if not np.array_equal(rounded_predictions4[i][j], input_data_symbols_test[i][j]):\n",
    "            channel = channel_test[i]\n",
    "            for key in statistics_count:\n",
    "                if mean_squared_error(channel, np.array(key)) < 0.1:\n",
    "                    statistics_count[key] += 1\n",
    "                    error = mean_squared_error(predictions4[i][j], input_data_symbols_test[i][j])\n",
    "                    statistics_errors[key] += error\n",
    "#       print('Channel', channel_test[i])\n",
    "#       print('Prediction', predictions4[i][j])\n",
    "#       print('QPSK Prediction', rounded_predictions4[i][j])\n",
    "#       print('True QPSK', input_data_symbols_test[i][j])\n",
    "            bad_channel_errors.append(mean_squared_error(predictions4[i][j], input_data_symbols_test[i][j]))\n",
    "    else:\n",
    "        good_channel_errors.append(mean_squared_error(predictions4[i][j], input_data_symbols_test[i][j]))\n",
    "\n",
    "for key in statistics_errors:\n",
    "    if statistics_count[key] > 0:\n",
    "        statistics_errors[key] = statistics_errors[key] / statistics_count[key]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 127,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Good channel error 0.0002638874699068144\n",
      "Bad channel error 0.7306372348726573\n",
      "Total Bad Channels 43\n",
      "{(0.707, 0.707): 14, (-0.707, 0.707): 1, (0.707, -0.707): 16, (-0.707, -0.707): 12, (0, -1): 0}\n",
      "{(0.707, 0.707): 0.7162300079403883, (-0.707, 0.707): 0.5236157671769702, (0.707, -0.707): 0.8172570317294764, (-0.707, -0.707): 0.64920439279252, (0, -1): 0}\n"
     ]
    }
   ],
   "source": [
    "print('Good channel error', sum(good_channel_errors) / len(good_channel_errors))\n",
    "print('Bad channel error', sum(bad_channel_errors) / len(bad_channel_errors))\n",
    "print('Total Bad Channels', len(bad_channel_errors))\n",
    "statistics_count_rounded = {}\n",
    "statistics_errors_rounded = {}\n",
    "for key in statistics_count:\n",
    "    rounded_key = (np.round(key[0], 3), np.round(key[1], 3))\n",
    "    statistics_count_rounded[rounded_key] = statistics_count[key]\n",
    "    statistics_errors_rounded[rounded_key] = statistics_errors[key]\n",
    "print(statistics_count_rounded)\n",
    "print(statistics_errors_rounded)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## MMSE Equalizer vs RNN Equalizer"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 151,
   "metadata": {},
   "outputs": [],
   "source": [
    "def generate_topleitz(row_vector, channel_length):\n",
    "    import scipy.linalg as la\n",
    "    first_row = row_vector[:channel_length]\n",
    "    first_col = row_vector\n",
    "    return la.toeplitz(first_col, first_row)\n",
    "\n",
    "def least_squares(A, b):\n",
    "    return np.linalg.lstsq(A, b)[0]\n",
    "\n",
    "def perform_least_squares(preamble, preamble_convolved, channel_length):\n",
    "    A, b = generate_topleitz(preamble, channel_length), preamble_convolved\n",
    "    prediction = least_squares(A, b)\n",
    "    return np.array(prediction)\n",
    "\n",
    "def generate_A_hat(channel_estimate, data_length):\n",
    "    matrix = np.zeros((data_length, data_length), dtype='complex')\n",
    "    for i in range(data_length - 1): \n",
    "        matrix[i][i] = channel_estimate[0]\n",
    "        matrix[i+1][i] = channel_estimate[1]\n",
    "    matrix[data_length - 1][data_length - 1] = channel_estimate[0]\n",
    "    return matrix\n",
    "\n",
    "# MMSE\n",
    "\n",
    "def MMSE_equalization_QPSK_SVD(channel_estimate, data_convolved, data_length, snr):\n",
    "    std = 10 ** (-snr / 20)\n",
    "    A_hat = generate_A_hat(channel_estimate, data_length)\n",
    "\n",
    "    A_hat = np.asmatrix(A_hat)\n",
    "    to_invert = np.dot(A_hat, A_hat.H) + (std ** 2) * np.identity(data_length)\n",
    "    eigenvalues, eigenvectors = np.linalg.eig(to_invert)\n",
    "    eigenvalues_2, eigenvectors_2 = np.linalg.eig(np.dot(A_hat, A_hat.H))\n",
    "    B = np.dot(np.linalg.pinv(to_invert), A_hat)\n",
    "    data_est = np.dot(B.H, data_convolved)\n",
    "    return data_est\n",
    "\n",
    "def run_MMSE(convolved_data_full, channels, input_data_constellations, snr):\n",
    "    errors_MMSE = []\n",
    "    i = 0\n",
    "    for convolved_data, channel, input_data_constellation in zip(convolved_data_full, channels, input_data_constellations):\n",
    "#         print(i)\n",
    "        convolved_data = tranform_2d_array_into_complex(convolved_data)\n",
    "        input_data_constellation = tranform_2d_array_into_complex(input_data_constellation)\n",
    "        lms_test_output = MMSE_equalization_QPSK_SVD(channel, convolved_data, input_data_constellation.shape[0], snr)\n",
    "        lms_mse = mse_middle(lms_test_output, input_data_constellation, 10)\n",
    "#         print(lms_mse)\n",
    "        errors_MMSE.append(lms_mse)\n",
    "        i += 1\n",
    "    return np.mean(np.array(errors_MMSE))\n",
    "\n",
    "def tranform_2d_array_into_complex(arr):\n",
    "    new_array = np.zeros(arr.shape[0], dtype='complex')\n",
    "    new_array.real = arr[:, 0]\n",
    "    new_array.imag = arr[:, 1]\n",
    "    return new_array\n",
    "def mse_middle(predicted_signal, test_signal, index):\n",
    "    predicted_signal = np.array(predicted_signal).flatten()\n",
    "#     print(predicted_signal.shape)\n",
    "    predicted_signal = predicted_signal[index:(len(test_signal) - index)]\n",
    "    test_signal = test_signal[index:(len(test_signal) - index)]\n",
    "#     print(predicted_signal.shape, test_signal.shape)\n",
    "    from sklearn.metrics import mean_squared_error\n",
    "    real_test_sig, real_predicted_sig = np.real(test_signal), np.real(predicted_signal)\n",
    "    imag_test_sig, imag_predicted_sig = np.imag(test_signal), np.imag(predicted_signal)\n",
    "    real_im_test = np.vstack((real_test_sig, imag_test_sig)).T\n",
    "    real_im_predicted = np.vstack((real_predicted_sig, imag_predicted_sig)).T\n",
    "    return mean_squared_error(real_im_test, real_im_predicted)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 142,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(40000, 160) (10000, 160)\n",
      "(40000, 30, 2) (10000, 30, 2)\n",
      "(40000, 30, 2) (10000, 30, 2)\n",
      "(40000, 2) (10000, 2)\n",
      "[[ 0.18674749  0.98240795]\n",
      " [ 0.81052259 -0.58570738]\n",
      " [-0.49947786 -0.86632665]\n",
      " ...\n",
      " [ 0.98481808 -0.17358962]\n",
      " [-0.85390431 -0.52043004]\n",
      " [ 0.45812146  0.8888896 ]]\n"
     ]
    }
   ],
   "source": [
    "## MMSE Data generation\n",
    "preamble_length = 80\n",
    "data_length = 60\n",
    "dataset_size = 50000\n",
    "channel_length = 2\n",
    "SNR = 100\n",
    "constellations = 4\n",
    "preamble_data, convolved_data, input_data_symbols, channels = generate_combined_dataset_qam_4_edited(dataset_size, preamble_length, data_length, channel_length, SNR, constellations)\n",
    "train_size = int(input_data_symbols.shape[0] * 0.8)\n",
    "preamble_train, preamble_test = preamble_data[:train_size], preamble_data[train_size:]\n",
    "convolved_train, convolved_test = convolved_data[:train_size], convolved_data[train_size:]\n",
    "input_data_symbols_train, input_data_symbols_test = input_data_symbols[:train_size], input_data_symbols[train_size:]\n",
    "channel_train, channel_test = channels[:train_size], channels[train_size:]\n",
    "print(preamble_train.shape, preamble_test.shape)\n",
    "print(convolved_train.shape, convolved_test.shape)\n",
    "print(input_data_symbols_train.shape, input_data_symbols_test.shape)\n",
    "print(channel_train.shape, channel_test.shape)\n",
    "print(channels)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 161,
   "metadata": {},
   "outputs": [],
   "source": [
    "def compare_RNN_and_MMSE():\n",
    "    SNRS = [1, 10, 50, 100, 500, 1000, 5000]\n",
    "    errors_RNN = []\n",
    "    errors_MMSE = []\n",
    "    for SNR in SNRS:\n",
    "        ## MMSE Data generation\n",
    "        print('SNR', SNR)\n",
    "        preamble_length = 80\n",
    "        data_length = 60\n",
    "        dataset_size = 50000\n",
    "        channel_length = 2\n",
    "        constellations = 4\n",
    "        preamble_data, convolved_data, input_data_symbols, channels = generate_combined_dataset_qam_4_edited(dataset_size, preamble_length, data_length, channel_length, SNR, constellations)\n",
    "        train_size = int(input_data_symbols.shape[0] * 0.8)\n",
    "        preamble_train, preamble_test = preamble_data[:train_size], preamble_data[train_size:]\n",
    "        convolved_train, convolved_test = convolved_data[:train_size], convolved_data[train_size:]\n",
    "        input_data_symbols_train, input_data_symbols_test = input_data_symbols[:train_size], input_data_symbols[train_size:]\n",
    "        channel_train, channel_test = channels[:train_size], channels[train_size:]\n",
    "        print('Finished generating data for MMSE')\n",
    "        error_MMSE = run_MMSE(convolved_test, channel_test, input_data_symbols_test, SNR)\n",
    "        print('Error MMSE', error_MMSE)\n",
    "        errors_MMSE.append(error_MMSE)\n",
    "        \n",
    "        # RNN Test Data Generation\n",
    "        window_length = 10\n",
    "        channels, convolved_data, input_data_symbols = transform_data(channels, convolved_data, input_data_symbols, data_length // 2, window_length=window_length)\n",
    "        train_size = int(input_data_symbols.shape[0] * 0.8)\n",
    "        preamble_train, preamble_test = preamble_data[:train_size], preamble_data[train_size:]\n",
    "        convolved_train, convolved_test = convolved_data[:train_size], convolved_data[train_size:]\n",
    "        input_data_symbols_train, input_data_symbols_test = input_data_symbols[:train_size], input_data_symbols[train_size:]\n",
    "        channel_train, channel_test = channels[:train_size], channels[train_size:]\n",
    "        print('Finished transforming data for RNN')\n",
    "        predictions4 = model4.predict([channel_test, convolved_test])\n",
    "        new_shape = (predictions4.shape[0] * predictions4.shape[1], 2)\n",
    "        predictions4 = predictions4.reshape(new_shape)\n",
    "        \n",
    "        input_data_symbols_test = input_data_symbols_test.reshape(new_shape)\n",
    "        error_RNN = mean_squared_error(predictions4, input_data_symbols_test)\n",
    "        print('Error RNN', error_RNN)\n",
    "        errors_RNN.append(error_RNN)\n",
    "    return SNRS, errors_RNN, errors_MMSE\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 162,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "SNR 1\n",
      "Finished generating data for MMSE\n",
      "Error MMSE 0.5165877097623547\n",
      "Finished transforming data for RNN\n",
      "Error RNN 0.640224685214764\n",
      "SNR 10\n",
      "Finished generating data for MMSE\n",
      "Error MMSE 0.3565397769004156\n",
      "Finished transforming data for RNN\n",
      "Error RNN 0.29007638268959374\n",
      "SNR 50\n",
      "Finished generating data for MMSE\n",
      "Error MMSE 0.03500069336586178\n",
      "Finished transforming data for RNN\n",
      "Error RNN 0.00488730360186191\n",
      "SNR 100\n",
      "Finished generating data for MMSE\n",
      "Error MMSE 0.06333870376876896\n",
      "Finished transforming data for RNN\n",
      "Error RNN 0.001992637938601211\n",
      "SNR 500\n",
      "Finished generating data for MMSE\n",
      "Error MMSE 2.4920730549456855e-08\n",
      "Finished transforming data for RNN\n",
      "Error RNN 0.002126244683376098\n",
      "SNR 1000\n",
      "Finished generating data for MMSE\n",
      "Error MMSE 2.6760707908787254e-08\n",
      "Finished transforming data for RNN\n",
      "Error RNN 0.001893772753789164\n",
      "SNR 5000\n",
      "Finished generating data for MMSE\n",
      "Error MMSE 2.242762227507016e-08\n",
      "Finished transforming data for RNN\n",
      "Error RNN 0.002181193583828374\n"
     ]
    }
   ],
   "source": [
    "SNRS, errors_RNN, errors_MMSE = compare_RNN_and_MMSE()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 171,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYQAAAEKCAYAAAASByJ7AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAIABJREFUeJzt3Xt0VOW9//H3lxgloIXKRYVw06NYJBdoilCkgqBSAbGiiFWPgF14Q6unoCA9Snv8WSpYCmqPdVUIKlXxUry0LipW6r02KLeicryADbQaaBNFghDy/f0xOyGXSTIhmdmTzOe11l6Zefaz9/PNTvZ859mXZ5u7IyIi0ibsAEREJDkoIYiICKCEICIiASUEEREBlBBERCSghCAiIoASgoiIBJQQREQEUEIQEZHAYWEH0BidO3f23r17hx2GiEiLsnbt2p3u3qWhei0qIfTu3ZuCgoKwwxARaVHMbFss9UI9ZGRmo83sfTP7wMxmhRmLiEiqCy0hmFkacC/wXaAfcLGZ9QsrHhGRVBdmD2EQ8IG7f+Tu+4BHgfEhxiMiktLCTAjdgb9XeV8YlImISAiS/rJTM5tmZgVmVlBUVBR2OCIirVaYCWE70KPK+8ygrBp3v9/d89w9r0uXBq+aEhGRQxTmZad/BU40sz5EEsEk4PvxbHDlO9uZv+p9dhSX0q1jBjPP7st5A3SUSkQEQkwI7l5mZtOBVUAasMTd/xav9la+s53ZT22kdP8BALYXlzL7qY0ASgoiIoR8Y5q7/wH4QyLamr/qfc488GduOnwF3WwnO7wzd5ZNZP6qw5UQRERoASeVm0ve5y8wL/03ZLbZSRuDzDY7mZf+G/I+fyHs0EREkkLKJITZhz9OO9tXrayd7WP24Y+HFJGISHJJmYRwDDsbVS4ikmpSJiFYh8xGlUsdNqyAhf1hbsfIzw0rwo5IRJpJyiQERt4K6RnVy9IzIuUSmw0r4NnroeTvgEd+Pnu9koJIK5E6CSF7IoxbDB16ABb5OW5xpFxi8+JPYX9p9bL9pZFyEWnxWtTzEJose6ISQFOUFDauXERalNTpIUiT7ck4tlHlItKyKCFIzO7cfxF7/PBqZXv8cO7cf1FIEYlIc1JCkJgt2z2IWft/QGF5Z8rdKCzvzKz9P2DZ7kFhhyYizSC1ziFIk3TrmMEzxafxzL7TqpV375hRxxIi0pKohyAxm3l2XzLS06qVZaSnMfPsviFFJCLNST0EiVnFIIAaQlykdVJCkEY5b0B3JQCRVkqHjEREBFBCEBGRgBKCiIgAISUEM7vQzP5mZuVmlhdGDCIiUl1YPYRNwPnAyyG1LyIiNYRylZG7vwtgZmE0LyIiUegcgoiIAHHsIZjZaiDaMJhz3P3pRqxnGjANoGfPns0UnYiI1BS3hODuo5ppPfcD9wPk5eV5c6xTRERq0yEjkUTSM6kliYV12en3zKwQGAL83sxWhRGHSELpmdSS5EJJCO7+O3fPdPcj3P0Ydz87jDhEEkrPpJYkp0NGIomiZ1JLklNCEEmUDpmNKxdJMCUEkUQZeSuk13i6XHpGpFwkCSghiCRK9kQYtxg69AAs8nPc4ki5SBLQA3JEqtqwInKSt6Qwcihn5K3N+4GdPVEJQJKWEoJIhYrLQiuuBKq4LBT0IS4pQYeMRCroslBJcUoIIhV0WaikOCUEkQq6LFRSnBKCSAVdFiopTglBpIIuC5UUp6uMRKrSZaGSwtRDEBERQAlBREQCSggiIgIoIYiISEAJQUREACUEEREJhPVM5flm9p6ZbTCz35lZxzDiEBGRg8LqIbwA9Hf3bGALMDukOEREJBBKQnD3P7p7WfD2TUCDxYiIhCwZziFMBZ6va6aZTTOzAjMrKCoqSmBYIiKpJW5DV5jZauDYKLPmuPvTQZ05QBmwvK71uPv9wP0AeXl5HodQRUSEOCYEdx9V33wzmwyMBUa6uz7oRURCFsrgdmY2GrgJON3d94QRg4iIVBfWOYR7gKOAF8xsnZndF1IcIiISCKWH4O7/EUa7Ig1Z+c525q96nx3FpXTrmMHMs/ty3oDuYYclkhB6HoJIYOU725n91EZK9x8AYHtxKbOf2gigpCApIRkuOxVJCvNXvV+ZDCqU7j/A/FXvhxSRSGIpIYgEdhSXNqpcpLVRQhAJdOuY0ahykdZGCUEkMPPsvmSkp1Ury0hPY+bZfUOKSCSxdFJZJFBx4lhXGUmqUkIQqeK8Ad2VACRl6ZCRiIgASggiIhLQISMRaVa627vpwtqGSggiCdTaPywTcbe3tmH86JCRSIJU7Ojbi0txDu7oK9/ZHnZozSbed3trG8aXEoJIgqTC0Bjxvttb2zC+lBBEEiQVhsaI993e2obxpYQgkiCpMDRGvO/21jaMLyUEkQRJhaExzhvQnZ+dn0X3jhkY0L1jBj87P6vZToZqG8aXtaTHGefl5XlBQUHYYYgcstZ+hUwiaBs2npmtdfe8BuuFkRDM7H+A8UA58Bkw2d13NLScEoKISOPFmhDCOmQ0392z3T0XeA64NaQ4REQkEEpCcPfPq7xtD7Sc41YiIq1UaHcqm9n/A/4TKAFG1FNvGjANoGfPnokJTkQkBcXtHIKZrQaOjTJrjrs/XaXebKCtu9/W0Dp1DkFEpPFiPYcQtx6Cu4+Ksepy4A9AgwlBRETip95zCGaWZmYLmrtRMzuxytvxwHvN3YaIiDROvT0Edz9gZqfFod15ZtaXyGWn24Cr4tCGiIg0QiyHjN4xs2eAx4EvKwrd/alDbdTdJxzqsiIiEh+xJIS2wC7gjCplDhxyQhARkeTTYEJw9ymJCERERMLV4I1pZpZpZr8zs8+C6Ukzy0xEcCIikjix3Km8FHgG6BZMzwZlIiLSisSSELq4+1J3LwumfKBLnOMSEZEEiyUh7DKzS4N7EtLM7FIiJ5lFRKQViSUhTAUmAv8E/gFcAOhEs4hIK1PvVUZmlgac7+7nJigeEREJSb09BHc/AFycoFhERCREsdyY9pqZ3QM8RvU7ld+OW1QiIpJwsSSE3ODnT6uUOdXvXBYRkRauoXMIbYD/dfcVCYpHRERC0tA5hHLgpgTFIiIiIYrlstPVZjbDzHqY2dEVU9wjExGRhIrlHMJFwc9rq5Q5cHzzhyMiImGJZbTTPokIREREwlXnISMzu6nK6wtrzLsjnkGJiEji1XcOYVKV17NrzBvdHI2b2Y/MzM2sc3OsT0REDl19CcHqeB3tfaOZWQ/gLOCTpq5LRESarr6E4HW8jvb+UCwkcklrc6xLRESaqL6Tyjlm9jmR3kBG8JrgfdumNGpm44Ht7r7erMmdDRERaQZ1JgR3T2vKis1sNXBslFlzgFuIHC6KZT3TgGkAPXv2bEpIIiJSD3NP7BEbM8sCXgT2BEWZwA5gkLv/s75l8/LyvKCgIM4Rioi0Lma21t3zGqoXy41pzcrdNwJdK96b2VYgz913JjoWERE5KJahK0REJAUkvIdQk7v3DjsGERGJISGY2RfUvjS0BCgAfuTuH8UjMBERSaxYegi/BAqB3xK55HQScALwNrAEGB6v4EREJHFiOYdwrrv/2t2/cPfP3f1+4Gx3fwz4epzjExGRBIklIewxs4lm1iaYJgJ7g3m6y1hEpJWIJSFcAlwGfBZMlwGXmlkGMD2OsYmISALF8jyEj4Bxdcx+tXnDERGRsDTYQzCzTDP7nZl9FkxPmllmIoITEZHEieWQ0VLgGaBbMD0blImISCsSS0Lo4u5L3b0smPKBLnGOS0REEiyWhLDLzC41s7RguhTYFe/AREQksWJJCFOBicA/gX8AFwCT4xiTiIiEoMGE4O7b3P1cd+/i7l3d/TxgQgJiExGRBDrU0U7/q1mjEBGR0B1qQtBzL0VEWplDTQgaskJEpJWp807lOoa9hkjvICNuEYmISCjqTAjuflQiAxERkXCF8ghNM5trZtvNbF0wnRNGHCIiclCYj9Bc6O4LQmxfRESqCKWHICIiySfMhDDdzDaY2RIz05PXRERCFreEYGarzWxTlGk88L9EnsucS2Q4jLvqWc80Mysws4KioqJ4hSsikvLMPdxbCsysN/Ccu/dvqG5eXp4XFBTEPSYRkdbEzNa6e15D9cK6yui4Km+/B2wKIw4RETkorKuM7jSzXCI3vm0FrgwpDhERCYSSENz9sjDaFRGRuumyUxERAZQQREQkoIQgIiKAEoKIiASUEEREBFBCEBGRgBKCiIgASggiIhJQQhAREUAJQUREAkoIIiICKCGIiEhACUFERAAlBBERCSghiIgIoIQgIiIBJQQREQGUEEREJBBaQjCz68zsPTP7m5ndGVYcIiISEcozlc1sBDAeyHH3r8ysaxhxiIjIQWH1EK4G5rn7VwDu/llIcYiISCCshHASMMzM/mJmfzazb9VV0cymmVmBmRUUFRUlMEQRkdQSt0NGZrYaODbKrDlBu0cDg4FvASvM7Hh395qV3f1+4H6AvLy8WvNFRKR5xC0huPuouuaZ2dXAU0ECeMvMyoHOgLoAIiIhCeuQ0UpgBICZnQQcDuwMKRYRESGkq4yAJcASM9sE7AMuj3a4SEREEieUhODu+4BLw2hbRESi053KIiICKCGIiEhACUFERAAlBBERCSghiIgIoIQgIiIBJQQREQGUEEREJKCEICIigBKCiIgElBBERAQIb3C7ZrN//34KCwvZu3dv2KFICmjbti2ZmZmkp6eHHYpIs2vxCaGwsJCjjjqK3r17Y2ZhhyOtmLuza9cuCgsL6dOnT9jhiDS7Fn/IaO/evXTq1EnJQOLOzOjUqZN6o9JqtfiEACgZSMLof01as1aREMKWlpZGbm4u/fv3Z9y4cRQXFwOwdetWzIy77767su706dPJz88HYPLkyXTv3p2vvvoKgJ07d9K7d+9626iY5s2bF9ffqSl++ctfsmfPnkNaduXKlWzevDmmukceeWS984uLi/nVr351SHGIpCIlhGaQkZHBunXr2LRpE0cffTT33ntv5byuXbuyaNEi9u3bF3XZtLQ0lixZEnMbFdOsWbNq1Tlw4EC192VlZTHFH2u9WCUqITRECUGkcUJJCGb2mJmtC6atZrYuUW2vfGc7Q+f9iT6zfs/QeX9i5Tvbm3X9Q4YMYfv2g+vs0qULI0eOZNmyZVHr33DDDSxcuPCQP5R79+7NzTffzMCBA3n88ccZPnw4N9xwA3l5eSxatIitW7dyxhlnkJ2dzciRI/nkk0+ASO/kqquu4tRTT+Wmm26qts69e/cyZcoUsrKyGDBgAC+99BIA+fn5nH/++YwePZoTTzyx1nIAixcvZseOHYwYMYIRI0YA8Mc//pEhQ4YwcOBALrzwQnbv3g3ArFmz6NevH9nZ2cyYMYPXX3+dZ555hpkzZ5Kbm8uHH35Ybd0ff/wxQ4YMISsrix//+MeV5bt372bkyJEMHDiQrKwsnn766cr1f/jhh+Tm5jJz5sw664lIwN1DnYC7gFtjqfvNb37Ta9q8eXOtsrr87u1CP/nHz3uvm5+rnE7+8fP+u7cLY15HNO3bt3d397KyMr/gggv8+eefd3f3jz/+2E855RT/8MMP/aSTTvKysjK/9tprfenSpe7ufvnll/vjjz/uU6ZM8SVLlnhRUZH36tUrahtt2rTxnJycyunRRx91d/devXr5z3/+88p6p59+ul999dWV78eOHev5+fnu7v7AAw/4+PHjK9seM2aMl5WV1WprwYIFPmXKFHd3f/fdd71Hjx5eWlrqS5cu9T59+nhxcbGXlpZ6z549/ZNPPqm1fK9evbyoqMjd3YuKinzYsGG+e/dud3efN2+e/+QnP/GdO3f6SSed5OXl5e7u/u9//7vaNolm3LhxvmzZMnd3v+eeeyq3+/79+72kpKSyvRNOOMHLy8srt3+Fuuo1VmP+50SSAVDgMXzGhnrZqUXO0E0EzkhEe/NXvU/p/uqHVUr3H2D+qvc5b0D3Q15vaWkpubm5bN++nW984xuceeaZ1eYff/zxnHrqqfz2t7+Nuvzs2bMZP348Y8aMqbONikNG0Vx00UV1vn/jjTd46qmnALjsssuqfau/8MILSUtLq7W+V199leuuuw6Ak08+mV69erFlyxYARo4cSYcOHQDo168f27Zto0ePHnXG/eabb7J582aGDh0KwL59+xgyZAgdOnSgbdu2XHHFFYwdO5axY8fWuY4Kr732Gk8++WTl73LzzTcDkS81t9xyCy+//DJt2rRh+/btfPrpp7WWr6vescce22DbIqkg7HMIw4BP3f3/EtHYjuLSRpXHquLDetu2bbh7tXMIFW655RZ+/vOfV/SKqjnxxBPJzc1lxYoVh9R++/bt630f63KxOOKIIypfp6WlNXioy90588wzK899bN68mQceeIDDDjuMt956iwsuuIDnnnuO0aNHx9R+tKt8li9fTlFREWvXrmXdunUcc8wxUS8NjbWeSKqKW0Iws9VmtinKNL5KtYuBRxpYzzQzKzCzgqKioibF1K1jRqPKG6tdu3YsXryYu+66q9YH5cknn0y/fv149tlnoy47Z84cFixY0CxxVPXtb3+bRx99FIh8IA4bNqzBZYYNG8by5csB2LJlC5988gl9+/aNuc2jjjqKL774AoDBgwfz2muv8cEHHwDw5ZdfsmXLFnbv3k1JSQnnnHMOCxcuZP369bWWrWno0KHVfpcKJSUldO3alfT0dF566SW2bdsWdV111RORiLglBHcf5e79o0xPA5jZYcD5wGMNrOd+d89z97wuXbo0KaaZZ/clI736IZKM9DRmnh37h11DBgwYQHZ2No88UjvPzZkzh8LCwqjLnXLKKQwcOLDO9VYclqqYol1lFM3dd9/N0qVLyc7O5qGHHmLRokUNLnPNNddQXl5OVlYWF110Efn5+dV6Bg2ZNm0ao0ePZsSIEXTp0oX8/HwuvvhisrOzGTJkCO+99x5ffPEFY8eOJTs7m9NOO41f/OIXAEyaNIn58+czYMCAWieVFy1axL333ktWVla1E/eXXHIJBQUFZGVl8eCDD3LyyScD0KlTJ4YOHUr//v2ZOXNmnfVEJMKiHcJISMNmo4HZ7n56rMvk5eV5QUFBtbJ3332Xb3zjGzG3u/Kd7cxf9T47ikvp1jGDmWf3bdL5A0k9jf2fEwmbma1197yG6oV5UnkSDRwuiofzBnRXAhARiSK0hODuk8NqW0REagv7KiMREUkSSggiIgIoIYiISEAJQUREACWEZmFmXHrppZXvy8rK6NKlS+VwDPn5+ZgZq1evrqyzcuVKzIwnnngCgOeee44BAwaQk5NDv379+PWvfw3A3Llz6d69e7V7ECqG166wdetWMjIyqtV58MEH4/1rH7I77rjjkJfNz89nx44dDdbbunUr/fv3b7BOXcOJiKSiFv8IzWTQvn17Nm3aRGlpKRkZGbzwwgt071790tasrCweffRRRo0aBcAjjzxCTk4OEHku9LRp03jrrbfIzMzkq6++YuvWrZXL3njjjcyYMaPeGE444YQ6xzqqcODAgWpjF9V8X5eysjIOO6z5/lXuuOMObrnllkNaNj8/n/79+9OtW7cmx1GREL7//e83eV0irUHq9RA2rICF/WFux8jPDYc2flBN55xzDr///e+ByIf9xRdfXG3+sGHDeOutt9i/fz+7d+/mgw8+IDc3F4AvvviCsrIyOnXqBETGC2rMUBH1OfLII/nRj35ETk4Ob7zxRq3hstetW8fgwYPJzs7me9/7Hv/+978Bag2jXdW//vUvzjvvPLKzsxk8eDAbNmwAIr2ZqVOnMnz4cI4//ngWL15cK55Zs2ZV3nV9ySWXAPDwww8zaNAgcnNzufLKKzlw4AAHDhxg8uTJ9O/fn6ysLBYuXMgTTzxBQUEBl1xyCbm5uZSWVh+Dau3ateTk5JCTk1NtPKmtW7cybNgwBg4cyMCBA3n99dcrY3nllVfIzc1l4cKFddYTSRmxDImaLFNTh7/29Y+5336M+21fOzjdfkykvAnat2/v69ev9wkTJnhpaann5OT4Sy+95GPGjHF396VLl/q1117rN954oz/77LP+8MMP+9y5c6sN9XzFFVd4ly5dfNKkSf7www/7gQMH3N39tttu827dulUOez18+PBa7X/88cfetm3basNjv/zyy+7uDvhjjx38/WoOl52VleVr1qxxd/f//u//9h/+8IfuXnsY7aqmT5/uc+fOdXf3F1980XNycipjHTJkiO/du9eLior86KOP9n379kXdXhU2b97sY8eOrax39dVX+7Jly7ygoMBHjRpVWa9ieOzTTz/d//rXv0aNKysry//85z+7u/uMGTMqh77+8ssvvbS01N3dt2zZ4hX/R1X/RvXVq0nDX4ds/WPuvzjF/bYOkZ9N3H9TAS1h+OuEe/GnsL/GyKb7SyPl2RObtOrs7Gy2bt3KI488wjnnnBO1zqRJk1i8eDElJSXcdddd1Y6l/+Y3v2Hjxo2sXr2aBQsW8MILL1Q+arMph4zS0tKYMGFCtbKK4bFLSkooLi7m9NMjo4dcfvnlXHjhhbXq1fTqq69WDkN9xhlnsGvXLj7//HMAxowZwxFHHMERRxxB165d+fTTT8nMzKwz7hdffJG1a9fyrW99C4iM2dS1a1fGjRvHRx99xHXXXceYMWM466yz6v39i4uLKS4u5jvf+Q4QGR77+eefByKH5KZPn866detIS0urHMq7pljrSQM2rIjsUyWF0CETRt7a5P2r2rqfvf7gflzy98h7aL42UlhqJYSS6APL1VneSOeeey4zZsxgzZo17Nq1q9b8QYMGsXHjRtq1a8dJJ51Ua35WVhZZWVlcdtll9OnTpzIhNEXbtm1rnSdItuGxL7/8cn72s5/Vmrd+/XpWrVrFfffdx4oVK2J61Gg0Cxcu5JhjjmH9+vWUl5fTtm3bJtWTesT7AzuOX+qSSjyTaj1S6xxChzq+qdZV3khTp07ltttuIysrq8468+bNq3WVze7du1mzZk3l+3Xr1tGrV69miak+HTp04Otf/zqvvPIKAA899FBlb6E+VYfHXrNmDZ07d+ZrX/tazO2mp6ezf/9+IPLAnSeeeILPPvsMiJyf2LZtGzt37qS8vJwJEyZw++238/bbbwN1D4/dsWNHOnbsyKuvvgrUHh77uOOOo02bNjz00EOVz56ONjx2tHrSCPV9YDeHOH+pSwoVSbXk74AfTKrNdL6zPqnVQxh5a/VvLwDpGZHyZpCZmcn1119fb53vfve7tcrcnTvvvJMrr7ySjIwM2rdvX613sHDhQh5++OHK9ytXrqR3797V1lHx7OAKU6dObTAWgGXLlnHVVVexZ88ejj/+eJYuXdrgMhUnj7Ozs2nXrl2dz4uuy7Rp08jOzmbgwIEsX76c22+/nbPOOovy8nLS09O59957ycjIYMqUKZSXlwNU9iAqngWdkZHBG2+8QUbGwWdZLF26lKlTp2Jm1Q4xXXPNNUyYMIEHH3yQ0aNHV/Z8srOzSUtLIycnh8mTJ9dZTxoh3h/YHTKDD8oo5a1FiL2g0Ia/PhTNMfx1WF0xaT00/HU9Fvav4wO7B9y4qenrr3lICiJf6sYtbj378dyOQLTPZYO5xVHKG9YShr8OR/bE1vOPI5Js4twLr9x3W/OXuhB7QamXEEQkfhLxgd3av9TFO6nWQwlBRJpXa//AjrcQe0GtIiG4O2YWdhiSAlrSOTdpwUJKqqFcdmpmuWb2ppmtM7MCMxt0qOtq27Ytu3bt0o4qcefu7Nq1S/cnSKsVVg/hTuAn7v68mZ0TvB9+KCvKzMyksLCQoqKi5oxPJKq2bdvWe+e1SEsWVkJwoOJOpg5Aw+MZ1yE9PZ0+ffo0S1AiIqksrIRwA7DKzBYQOWz17ZDiEBGRQNwSgpmtBo6NMmsOMBK40d2fNLOJwAPAqDrWMw2YBtCzZ884RSsiIqHcqWxmJUBHd3eLXB5U4u4NDoYT7U5lERGpX7LfqbwDOB1YA5wB/F8sC61du3anmW1rhvY7AzubYT3xkuzxQfLHqPiaLtljTPb4IHlijGm0zLB6CKcBi4gkpL3ANe6+NoHtF8SSLcOS7PFB8seo+Jou2WNM9vigZcRYVSg9BHd/FfhmGG2LiEh0qfU8BBERqVOqJoT7ww6gAckeHyR/jIqv6ZI9xmSPD1pGjJVa1PMQREQkflK1hyAiIjW06oRgZqPN7H0z+8DMZkWZf4SZPRbM/4uZ9U6y+CabWVEwCOA6M/tBguNbYmafmVnUR11ZxOIg/g1mNjDJ4htuZiVVtl/8B5Sv3n4PM3vJzDab2d/M7IdR6oS9DWOJMbTtaGZtzewtM1sfxPeTKHVC249jjC/U/bhR3L1VTkAa8CFwPHA4sB7oV6PONcB9wetJwGNJFt9k4J4Qt+F3gIHApjrmnwM8DxgwGPhLksU3HHguxO13HDAweH0UsCXK3zjsbRhLjKFtx2C7HBm8Tgf+AgyuUSfM/TiW+ELdjxszteYewiDgA3f/yN33AY8C42vUGQ9UPCH+CWCkJe7BCrHEFyp3fxn4Vz1VxgMPesSbQEczOy4x0cUUX6jc/R/u/nbw+gvgXaB7jWphb8NYYgxNsF12B2/Tg6nmic/Q9uMY42sxWnNC6A5UfTBpIbX/0SvruHsZUAJ0Skh0scUHMCE4lPCEmfVITGgxi/V3CNOQoDv/vJmdElYQwWGMAUS+QVaVNNuwnhghxO1oZmlmtg74DHjB3evchiHsx7HEB8m9H1dqzQmhNXgW6O3u2cALHPwWJLF5G+jl7jnA3cDKMIIwsyOBJ4Eb3P3zMGJoSAMxhrod3f2Au+cCmcAgM+ufyPYbEkN8LWY/bs0JYTtQNRNnBmVR65jZYUSezbArIdHFEJ+773L3r4K3vyH57u6OZRuHxt0/r+jOu/sfgHQz65zIGMwsncgH7XJ3fypKldC3YUMxJsN2DNouBl4CRteYFeZ+XKmu+FrAflypNSeEvwInmlkfMzucyMmmZ2rUeQa4PHh9AfAnD84CJUN8NY4ln0vk+G4yeQb4z+BKmcFERq39R9hBVTCzYyuOJVvkMa1tSOAHRdD2A8C77v6LOqqFug1jiTHM7WhmXcysY/A6AzgTeK8b6HHKAAACwElEQVRGtdD241jiawH7caWwRjuNO3cvM7PpwCoiV/Qscfe/mdlPgQJ3f4bIjvCQmX1A5OTkpCSL73ozOxcoC+KbnKj4AMzsESJXmHQ2s0LgNiInzXD3+4A/ELlK5gNgDzAlyeK7ALjazMqAUmBSAhM+wFDgMmBjcIwZ4BagZ5UYQ92GMcYY5nY8DlhmZmlEEtEKd38uWfbjGOMLdT9uDN2pLCIiQOs+ZCQiIo2ghCAiIoASgoiIBJQQREQEUEIQEZGAEoKkLDPb3XCtRq9zTjDq5YZgZMtTg/I1ZlZQpV6ema0JXlcdTfQ9M1vQ3HGJxEIJQaSZmNkQYCyR0UOzgVFUH6eoq5l9t47FXwmGPxgAjDWzofGNVqQ2JQSRKsyst5n9KfiG/6KZ9QzKTzCzN81so5ndXkfv4jhgZ8UwBe6+0913VJk/H5hTX/vuXgqsI/kGCZQUoIQgUt3dwLLgG/5yYHFQvghY5O5ZREYkjeaPQA8z22JmvzKz02vMfwPYZ2Yj6mrczL4OnAi83JRfQuRQKCGIVDcE+G3w+iHgtCrljwevf1tzIYBgALhvAtOAIuAxM5tco9rtwI+jLD7MzNYTGahtlbv/81B/AZFDpYQg0oyCoZDXuPttwHRgQo35fwIyiDwdrapXguGlTwGuMLPchAQsUoUSgkh1r3NwcLRLgFeC129y8MM96uBpZtbXzE6sUpQLbItS9XbgpmjrcPePgXnAzY0LW6TplBAklbUzs8Iq038B1wFTzGwDkVFAKx46fwPwX0H5fxB5KldNRxIZ+XJzUK8fMLdmpeCZAkX1xHUf8B1L4MPiRUCjnYrExMzaAaXu7mY2CbjY3ZPqGdgiTdVqn4cg0sy+CdwTPCimGJgacjwizU49BBERAXQOQUREAkoIIiICKCGIiEhACUFERAAlBBERCSghiIgIAP8fEXtXUKnrLikAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x20fc70b38>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(np.log10(SNRS), np.log10(errors_RNN), label='RNN Error on test data')\n",
    "plt.scatter(np.log10(SNRS), np.log10(errors_MMSE), label='MMSE Error on test data')\n",
    "plt.xlabel('Log SNR')\n",
    "plt.ylabel('Log Error')\n",
    "plt.legend()\n",
    "plt.savefig('RNN_vs_MMSE.png', bbox_inches='tight')\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
